Edited at

Python+PyQueryでスクレイピング

More than 3 years have passed since last update.


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へのリンクだけ載せておきます。

https://gist.github.com/knoguchi/6952087