Python+PyQueryでスクレイピング


PyQuery

PythonにはPyQueryというjQueryライクなAPIを提供する便利なモジュールがあります。巷ではBeautifulSoupなどが流行っているようですが、断然PyQueryの方が使い易いです。ベースはlxmlなので性能と信頼性も担保されていると思います。

コンストラクタにurlを引き渡すとフェッチまで勝手にやってくれます。HTMLの文字列を引き渡したり、ファイルオブジェクトを引き渡すこともできます。その後はjQueryのセレクター同様の文字列を指定すればマッチするエレメントをすべて取得することができます。

ラムダ式や関数を引き渡すことで、各々のエレメントを操作することも可能です。jQueryを知っている方なら何ができるか想像がつくでしょう。詳しくはマニュアルをご覧ください!

DOMの操作例

セレクトしたエレメントに対して.each()メソッドで属性をあたえて見ます。classはPythonの予約語なのでclass_にするとHTMLのclassになります。

sample.py
from pyquery import PyQuery as pq


html = '''
<ul>
  <li> item 1 </li>
  <li> item 2 </li>
  <li> item 3 </li>
</ul>
'''

dom = pq(html)
dom('li').each(lambda index, node: pq(node).attr(class_='red', x='123'))

print dom

実行したところclass と 謎の属性xがセットされました。

<ul>
  <li x="123" class="red"> item 1 </li>
  <li x="123" class="red"> item 2 </li>
  <li x="123" class="red"> item 3 </li>
</ul>

classについてはdom('li').addClass('red')でも同じことができます。

画像URL取得サンプル

ウェブページをアクセスして画像のURLを抽出する、サンプルプログラムを作ってみました。imgタグをセレクトして.items()でそれぞれのエレメントにアクセスします。

img_scraper.py
#!/usr/bin/env python
from urlparse import urljoin
from pyquery import PyQuery as pq
from pprint import pprint

url = 'http://www.yahoo.co.jp'

dom = pq(url)
result = set()
for img in dom('img').items():
    img_url = img.attr['src']
    if img_url.startswith('http'):
        result.add(img_url)
    else:
        result.add(urljoin(url, img_url))

pprint(result)

結果は次のとおり

set(['http://i.yimg.jp/images/sicons/box16.gif',
     'http://k.yimg.jp/images/clear.gif',
     'http://k.yimg.jp/images/common/tv.gif',
     'http://k.yimg.jp/images/icon/photo.gif',
     'http://k.yimg.jp/images/new2.gif',
     'http://k.yimg.jp/images/sicons/ybm161.gif',
     'http://k.yimg.jp/images/top/sp/cgrade/iconMail.gif',
     'http://k.yimg.jp/images/top/sp/cgrade/icon_point.gif',
     'http://k.yimg.jp/images/top/sp/cgrade/info_btn-140325.gif',
     'http://k.yimg.jp/images/top/sp/cgrade/logo7.gif',
     'http://lpt.c.yimg.jp/im_sigg6mIfJALB8FuA5LAzp6.HPA---x120-y120/amd/20150208-00010001-dtohoku-000-view.jpg'])

imgタグの代わりにaタグを選択して、geventと組み合わせてリストを探索するようにすれば、あっという間にクローラーも作れます。

Google Finance スクレイパー

Google Financeから、財務諸表をスクレイピングするスクリプトです。長いのでGistへのリンクだけ載せておきます。