2011年06月12日

GAE/PでBeautifulSoupを使ってXMLやHTMLをパース。

以前にGAE for PythonでPythonの標準APIだけを使ってXMLパースする方法を紹介したが、今回は Beautiful Soup という、かなり便利な外部モジュールを利用してHTMLパース(Webスクレイピング)する方法を紹介する。

BeautifulSoupのインストールは至って簡単で、インストールと言っても BeautifulSoup.py をダウンロードしてきてGAEアプリのプロジェクトフォルダにコピーするだけだ。

現時点のGAEはPython2.x系で動作しているので、Beautiful Soupもそれに対応したバージョン3.0系のモジュールをダウンロードする必要がある。ちなみに俺は、v3.0.8をダウンロードした。

さて、BeautifulSoup.py をプロジェクトフォルダにコピーできたら、早速サンプルコードを書いてみよう。以下はお馴染みの helloworld.py だ。

helloworld.py
# -*- coding: utf-8 -*-
import cgi
import os
import logging
import urllib2
from BeautifulSoup import BeautifulSoup
from google.appengine.ext import webapp, db
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext.webapp import template

#
# メインハンドラ
#
class MainHandler(webapp.RequestHandler):
def get(self):
# html = urllib2.urlopen("http://取得したいページのURL")
html = '''<html>
<p>aaa</p>
<p id="hoge">bbb</p>
<p>ccc</p>
</html>'''

soup = BeautifulSoup(html)

logging.info(u'全てのPタグのText')
tags = soup.findAll('p')
for idx, tag in enumerate(tags):
logging.info("#%s %s" % (str(idx), tag.text))

logging.info(u'id="hoge" なPタグのText')
tags = soup.findAll('p', attrs={'id':'hoge'})
for idx, tag in enumerate(tags):
logging.info("#%s %s" % (str(idx), tag.text))

logging.info(u'id="hoge" なタグのText')
tags = soup.findAll(attrs={'id':'hoge'})
for idx, tag in enumerate(tags):
logging.info("#%s %s" % (str(idx), tag.text))

logging.info(u'全てのタグのid属性')
tags = soup.findAll()
for idx, tag in enumerate(tags):
try:
logging.info("#%s %s" % (str(idx), dict(tag.attrs)['id']))
except KeyError:
logging.info("#%s %s" % (str(idx), ""))

template_values = {}
path = os.path.join(os.path.dirname(__file__), 'index.html')
self.response.out.write(template.render(path, template_values))

application = webapp.WSGIApplication([('/', MainHandler)],
debug=True)

def main():
run_wsgi_app(application)

if __name__ == "__main__":
main()


index.html
<html>hello world!</html>


上のサンプルを実行すると以下のようにログが出力される。

INFO 2011-06-12 12:16:09,815 helloworld.py:25] 全てのPタグのText
INFO 2011-06-12 12:16:09,818 helloworld.py:28] #0 aaa
INFO 2011-06-12 12:16:09,819 helloworld.py:28] #1 bbb
INFO 2011-06-12 12:16:09,822 helloworld.py:28] #2 ccc
INFO 2011-06-12 12:16:09,823 helloworld.py:30] id="hoge" なPタグのText
INFO 2011-06-12 12:16:09,828 helloworld.py:33] #0 bbb
INFO 2011-06-12 12:16:09,831 helloworld.py:35] id="hoge" なタグのText
INFO 2011-06-12 12:16:09,835 helloworld.py:38] #0 bbb
INFO 2011-06-12 12:16:09,836 helloworld.py:40] 全てのタグのid属性
INFO 2011-06-12 12:16:09,839 helloworld.py:46] #0
INFO 2011-06-12 12:16:09,842 helloworld.py:46] #1
INFO 2011-06-12 12:16:09,842 helloworld.py:44] #2 hoge
INFO 2011-06-12 12:16:09,845 helloworld.py:46] #3
INFO 2011-06-12 12:16:09,897 dev_appserver.py:4151] "GET / HTTP/1.1" 200 -


Beautiful Soup を使えば非常にシンプルにHTMLやXMLの解析ができることが分かったかな。

とりあえず findAll メソッドだけ覚えておけば何とかなるだろう。

Beautiful Soup APIの詳細を知りたいなら本家サイトのドキュメントをご参照あれ


★追記 2011/06/22
BeautifulSoupで文字コードに悩まされたら、BeautifulSoupに食わせるhtmlを明示的にdecodeしよう。


ここはひとつポチっとよろしく。
人気ブログランキングへ

プログラミング Google App Engine
Dan Sanderson
オライリージャパン
売り上げランキング: 40082



posted by 寄り道退屈男 at 21:33 | Comment(0) | TrackBack(0) | GAE for Python
この記事へのコメント
コメントを書く
お名前: [必須入力]

メールアドレス: [必須入力]

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
※ブログオーナーが承認したコメントのみ表示されます。
この記事へのトラックバックURL
http://blog.sakura.ne.jp/tb/45941998
※ブログオーナーが承認したトラックバックのみ表示されます。
※言及リンクのないトラックバックは受信されません。

この記事へのトラックバック