【お知らせ】プログラミング記事の投稿はQiitaに移行しました。

Pythonでスクレイピング

Pythonスクレイピングをやってみました。個人的にはプル型パーサが使いやすいのですが、pulldomは妥当性チェックが厳しくHTMLにはそのまま使えないことが多いため、自作パーサを移植しました。

元の自作パーサ

xml7shi.pyがフルPython、xml7shi2.cppとxml7shi2.pyがC++移植版とラッパーです。C++版は10倍程度高速です。単純にDLL化してスクリプトと同じディレクトリに置けば動くはずです。

$ g++ -std=c++0x -O2 -shared -o xml7shi2.dll xml7shi2.cpp

言語固有の機能はほとんど使わないシンプルなパーサなので、簡単に移植できます。

サンプル

Yahoo!からトピックスを取って来る例です。

import urllib, xml7shi2

class MyURLopener(urllib.FancyURLopener):
    version = "Mozilla/4.0 (compatible; MSIE 6.0; Windows XP)"
urllib._urlopener = MyURLopener()

f = urllib.urlopen("http://www.yahoo.co.jp/")
xr = xml7shi2.reader(f.read().decode("utf_8"))
f.close()

if xr.find("div", {"class": "topicsindex"}):
    if xr.find("ul", {"class": "emphasis"}):
        for i in xr.each("a"):
            if xr.read(): print i + 1, xr.text

ジェネレータを使うことで、C#版よりも随分と簡単になっています。C#でもyieldを使えば同じことができますが、当時はそこまで思いつきませんでした。