はてなブログ エクスポートスクリプト in Python
はてなブログにはなぜかエクスポート機能が実装されていない。
私がこれを知ったのは最近のことだが、検索するとこれに対する不満が多いようだ。エクスポート機能がないという事はバックアップができないという事で、不慮の事故や誤操作に保険をかけておくことができない。個人のブログなら一つの思い出として済むかも知れないが、法人や団体が使っている場合はこのエクスポート(バックアップ)機能は必須になるかと思う。
「図書館支援プログラム」なんかを見るとそう言った団体にもはてなブログを広げていきたいようだが、エクスポートができないというのはブログを選択する際に減点対象になると考えられる。私も今までにいくつものサイトにブログを提供してきたが、管理側でバックアップが取れないものは考慮外としてきた。
と言う事で、「はてなブログ AtomPub APIのPython WSSEサンプルコード」、「はてなブログ AtomPub コレクションXML フォーマット仕様」記事からの通りはてなブログをエクスポートできるスクリプトを書いてみた。
- 作者: Mark Lutz,夏目大
- 出版社/メーカー: オライリージャパン
- 発売日: 2009/02/26
- メディア: 大型本
- 購入: 12人 クリック: 423回
- この商品を含むブログ (133件) を見る
エクスポートスクリプトは最下部に貼りつけるが、このスクリプトには欠点がある。スクリプトというか、はてなブログ自体がエクスポートを前提にしていないため現在には難が一つある。
下のスクリプトを実行すると簡易的なMT形式でファイルを出力するようにしている。だがそのMT形式内の文章はブログの記入モードのままで書きだすようにしてある。と言う事は、「はてな記法モード」で書かれている場合は「はてな記法モード」でエクスポートする。HTML形式でもエクスポート出来るのだが、HTML形式でエクスポートすると今後の編集が大変になるため意図的にこのようにしてある。
だが、はてなブログのインポート機能を使うとすべて「見たままモード」としてインポートされてしまう。これは「はてな記法モード」か「Markdownモード」のみで起こる現象になるが、現在のはてなブログではこれを使ってエクスポート、インポートをする際には避けることのできない問題になってしまう。
この問題を解決する方法としては、インポート機能を使わずにAtomPub APIを利用して全ての記事を投稿する方法と、インポートした後に全ての記事の記述モードを変更する方法の、2つがあるがどちらも別にスクリプトを実装する必要があるためプログラムを書けない人には敷居が高くなってしまう。
実際にこのスクリプト自体もPythonの実行環境やプログラムの実行経験がなければ敷居の高いものになるかと思う。そう思うので、自分のために作ったといえ「バックアップできない」事に不便を考えている人達のことを考え、はてなブログのバックアップ実行サービスを作ろうと思う。これは簡単に実装できるため近日中に製作しようかと思う。
但し注意して欲しいのは、もし同じようなサービスが展開されたとしても「絶対」に不用意に使ってはいけない。APIKeyを伝えるというのは「パスワード」を教えるのと同じ意味になるため、ブログに関する全ての権限を与えてしまうのと同じ事になる。よってブログに勝手に投稿することも出来れば全ての記事を削除することすら出来てしまう。「バックアップ」するつもりが「バックアップ前に全て削除される」という結果になってしまうので絶対に不用意に「API Key」を伝えてはならない。これは私に対しても同じ事だ。
また、このエクスポートサービスはWebサーバの帯域が必要なために少々コストがかかってしまう。もし応援してくださる方がいれば「Amazonほしい物リスト」か「Amazonギフト券」で捻出しようかと思う。提供いただける方がいればコメント頂きたい。。
以下がはてなブログのエクスポートスクリプト。使い方は「はてなブログ AtomPub APIのPython WSSEサンプルコード」と同様になる。
#!/usr/bin/python import datetime import random import hashlib import base64 import urllib2 from xml.dom import minidom userid = "UserID" apikey = "API Key" blogid = "Blog ID" apiurl = "http://blog.hatena.ne.jp/%s/%s/atom/entry" % ( userid, blogid) def make_wsse( userid, apikey): created_at = datetime.datetime.now().isoformat() + "Z" nonce = hashlib.sha1( str( random.random())).digest() digest = hashlib.sha1( nonce + created_at + apikey).digest() return 'UsernameToken Username="%s", PasswordDigest="%s", Nonce="%s", Created="%s"' % ( userid, base64.b64encode( digest), base64.b64encode( nonce), created_at) headers = { "X-WSSE": make_wsse( userid, apikey)} entries = [] url = apiurl end = False while True: request = urllib2.Request( url, headers=headers) response = urllib2.urlopen( request) dom = minidom.parseString( response.read()) links = dom.getElementsByTagName( "link") for link in links: if link.attributes["rel"].value == "next": url = link.attributes["href"].value break else: end = True for entry in dom.getElementsByTagName( "entry"): mt_entry = {} mt_entry["category"] = [] for node in entry.childNodes: if node.nodeType == node.ELEMENT_NODE: if node.tagName == "author": mt_entry["author"] = node.firstChild.firstChild.data elif node.tagName == "title": mt_entry["title"] = node.firstChild.data elif node.tagName == "updated": mt_entry["date"] = datetime.datetime.strptime( node.firstChild.data[:19], "%Y-%m-%dT%H:%M:%S").strftime( "%m/%d/%Y %H:%M:%S") elif node.tagName == "summary": mt_entry["excerpt"] = node.firstChild.data elif node.tagName == "content": mt_entry["body"] = node.firstChild.data elif node.tagName == "category": mt_entry["category"].append( node.attributes["term"].value) elif node.tagName == "app:control": if node.getElementsByTagName("app:draft")[0].firstChild.data == "no": mt_entry["status"] = "Publish" else: mt_entry["status"] = "Draft" entries.append( mt_entry) if end: break for entry in entries: print """ TITLE: %s AUTHOR: %s DATE: %s STATUS: %s %s ----- BODY: %s ----- EXCERPT: %s ----- -------- """ % ( entry["title"], entry["author"], entry["date"], entry["status"], "\nCATEGORY: ".join( ["",]+entry["category"]), entry["body"], entry["excerpt"])
- 作者: 辻真吾
- 出版社/メーカー: 技術評論社
- 発売日: 2010/04/24
- メディア: 大型本
- 購入: 19人 クリック: 199回
- この商品を含むブログ (59件) を見る
Pythonによるデータ分析入門 ―NumPy、pandasを使ったデータ処理
- 作者: Wes McKinney,小林儀匡,鈴木宏尚,瀬戸山雅人,滝口開資,野上大介
- 出版社/メーカー: オライリージャパン
- 発売日: 2013/12/26
- メディア: 大型本
- この商品を含むブログ (19件) を見る
パーフェクトPython (PERFECT SERIES 5)
- 作者: Pythonサポーターズ,露木誠,ルイス・イアン,石本敦夫,小田切篤,保坂翔馬,大谷弘喜
- 出版社/メーカー: 技術評論社
- 発売日: 2013/03/05
- メディア: 大型本
- 購入: 1人 クリック: 65回
- この商品を含むブログ (30件) を見る
- 作者: Tarek Ziade,稲田直哉,渋川よしき,清水川貴之,森本哲也
- 出版社/メーカー: KADOKAWA/アスキー・メディアワークス
- 発売日: 2010/05/28
- メディア: 大型本
- 購入: 33人 クリック: 791回
- この商品を含むブログ (90件) を見る