Pythonで、はてなブックマークを取得する

Pythonで、はてなAPIを使ってみる(1) - シコウサクゴ()
この続きで、今度は各ユーザーのはてなブックマークのデータを取得します。これについてはAPIというよりは、一般的なRSSの取り方の説明になると思います。
さて、各ユーザーのはてなブックマークは、
はてなブックマーク - yosshi71jpのブックマーク
上のようなページになっていますが、このデータを取得するときはRSSを利用します。このページをRSS形式にするには、アドレスの最後に「rss」と付け加えればよく、上の場合は
http://b.hatena.ne.jp/yosshi71jp/rss
RSS形式のページをみることができます。
こうなると、Pythonでこのデータをとることは簡単です。

はてなブックマークデータを取得する

必要なモジュールのインポート
In [1]: import feedparser

今回はfeedparserを使いました。feedparserは標準モジュールではないので、インストールする必要があります。http://www.feedparser.org/

feedparserでRSSデータを取得
In [2]: feed = feedparser.parse('http://b.hatena.ne.jp/yosshi71jp/rss')

これだけでデータを取ってこれます。素晴らしく簡単です。例のように、何がとってこれたのかを調べます。

In [3]: feed.keys()
Out[3]:
['feed',
 'status',
 'version',
 'encoding',
 'bozo',
 'headers',
 'etag',
 'href',
 'namespaces',
 'entries']

例えば、feedの中は

In [6]: feed['feed']
Out[6]:
{'entries': u'',
 'itemsperpage': u'20',
 'link': u'http://b.hatena.ne.jp/yosshi71jp/',
 'links': [{'href': u'http://b.hatena.ne.jp/yosshi71jp/',
            'rel': 'alternate',
            'type': 'text/html'}],
 'rdf_li': u'',
 'rdf_seq': u'',
 'startindex': u'1',
 'subtitle': u'yosshi71jp \u306e\u30d6\u30c3\u30af\u30de\u30fc\u30af',
 'subtitle_detail': {'base': 'http://b.hatena.ne.jp/yosshi71jp/rss',
                     'language': None,
                     'type': 'text/html',
                     'value': u'yosshi71jp \u306e\u30d6\u30c3\u30af\u30de\u30fc\u30af'},
 'title': u'yosshi71jp \u306e\u30d6\u30c3\u30af\u30de\u30fc\u30af',
 'title_detail': {'base': 'http://b.hatena.ne.jp/yosshi71jp/rss',
                  'language': None,
                  'type': 'text/plain',
                  'value': u'yosshi71jp \u306e\u30d6\u30c3\u30af\u30de\u30fc\u30af'},
 'totalresults': u'16'}

キーのtitleやsubtitleの値が文字化けのように見えていますが、ちゃんとprintすれば、

In [7]: print feed['feed']['title']
------> print(feed['feed']['title'])
yosshi71jp のブックマーク

というように、ちゃんと日本語を出力することができます。あんまり文字コードの心配もしなくてよさそうです。(わかっている限りでは、EUCでは使えない文字(記号)がたまにタイトルに入っていたりして、それをprintするときにエラーが発生します)

ブックマーク情報を見る

さて、最も必要なのはここからで、今からはユーザー(今はyosshi71jp)のブックマークを見ていきます。ブックマークの情報はentriesというキーの中に入っています。

In [11]: print feed['entries'][0]['title']
-------> print(feed['entries'][0]['title'])
シコウ?サクゴ?

In [12]: print feed['entries'][0]['link']
-------> print(feed['entries'][0]['link'])
http://d.hatena.ne.jp/yosshi71jp/

In [14]: print feed['entries'][0]['updated']
-------> print(feed['entries'][0]['updated'])
2009-07-15T19:09:43+09:00

entriesの中には20件のブックマークデータがあります。その中にデータは格納されていて、今は0番目(一番最近)のブックマークの情報を見ています。他にもいろんな情報が入っていますので、見てみてください。
ただ、一つ気をつけなければいけないのは、1回では20件のブックマークデータしかとってこれないということです。下では20番目(実質21番目)のデータを見ようとしていますが、データはないので、エラーが返ってきます。

In [17]: print feed['entries'][20]['title']
-------> print(feed['entries'][20]['title'])
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)


IndexError: list index out of range

だから、何回もfeedparserを動かす必要があるわけですが、ただ単に何回もやったって、同じデータを取り続けるだけです。
じゃあ、20番目以降はどうするのかというと、アドレスのrssの後ろに「?of=20」と書くことにより、21番目からの20件のデータを取ってくれます。なので、この辺はfor文を工夫してやるべきですところですね。

まとめ

以上をやることで、はてなのユーザーのブックマークを取得することができます。僕はこれでネットワークデータをつくるという目的を果たすつもりです。ただ、問題はスピードで、20件ずつしかとってこれないので、5000とかブックマークしているユーザーに当たったときには大変です。個人的には、データの取得回数を最小にできるような方法を探ってみたいと思います。