Hatena::Groupbugrammer

蟲!虫!蟲!

Esehara Profile Site (by Heroku) / Github / bookable.jp (My Service)
過去の記事一覧はこちら

なにかあったら「えせはら あっと Gmail」まで送って頂ければ幸いです。
株式会社マリーチでは、Pythonやdjango、また自然言語処理を使ったお仕事を探しています

 | 

2011-12-04Python Advent Calender(全部俺):: 四日目

[]BeautifulSoup、Mechanizeでおいしくデータをすする -- PythonによるWebスクレイピング 02:16

 例えば、Webサイトのデータを習得したいときに使われる標準モジュールとして、urllib2というのがあります。基本的に、urllib2はセッションの無いときに使えるものですが、どうしてもセッション要求してくるサイトというのがあります。そういうときに使いたいのがMechanizeです。

Mechanizeってなに?

 いわゆるブラウザを擬似的にエミュレートしてくれるモジュール。元がPerl版らしく、そのあとにRubyPythonに移植されました。普通にサイトのHTMLを落とすだけだったら、urllib2を使えばいいのですけど、例えば認証が必要なサイトだったりすると困ったりします。そういった場合には、Mechanizeを使って、そこから操作を行うと、セッションの保存などを自動的に行ってくれるので、楽に要認証のサイトのスクレイピングを行うことが可能です。

 例えば、はてなブックマークに、任意のURLブックマークするスクリプトを書いてみましょう。(過去記事参照:自分でブックマークするのもだるくなってきたので、ロボットにブックマークの選別を頼んだ - 蟲!虫!蟲! - #!/usr/bin/bugrammer )

import mechanize
class Hatena:
    def __init__(self,name,password):
        self.br = mechanize.Browser()
        self.br.open("http://www.hatena.ne.jp/login")
        self.br.select_form(nr=0)
        self.br["name"] = name
        self.br["password"] = password
        res = self.br.submit()
        self.name = name
    
    def post(self,entry_url):
        self.br.open("http://b.hatena.ne.jp/" + self.name + "/add.confirm?url=" + entry_url)
        self.br.select_form(nr=1)
        self.br.submit()
    
def HateBu(slef):
    Robot = Hatena("FIXME:id","FIXME:pass")
    Robot.post("http://bugrammer.g.hatena.ne.jp/nisemono_san/")

if __name__ = "__main__":Hatena().Hatebu()

 と、こうなります。簡単に説明すると、下の項目のようにわけられます。

  • まずmechanizeはBrowserを呼び出すことによって、初期化されます。
  • openによって、対象のURLを開きます。
  • select_formで、フォームを選択します(番号、またはname="hoge"の指定も可能)。
  • フォームの入力部分は連想配列で格納されます。
  • submit()でフォーム内容を送信します

 これが基本です。もっと詳しく知りたい人は、オフィシャルサイトにソースがあるので、それを見るといいでしょう(mechanize)。

BeautifulSoup

 さて、もう一つの定番モジュールにBeautifulSoupというのが存在しています。BeautifulSoupというのは、HTML/XMLパーサーなのですが、不完全なタグなどを保管してくれたり、かなりの強力な力を持っています。BeautifulSoupを使いこなすことによって、サイトの情報を効率よく取り出すことが可能になります。

 例えば、ツイコレというサイトから、任意のタグのUser名をすべて取得し、ファイルに保存するようなスクリプトを書いてみましょう。

import urllib2
import BeautifulSoup
import sys
argvs = sys.argv

if len(argvs) != 3:
    print "Usage:python myself.py [keyword] [filename]"
    exit()

html = urllib2.urlopen("http://twkr.in/tag/" + argvs[1]).read()
soup = BeautifulSoup.BeautifulSoup(html)

userfile = open(argvs[2],"w")
for span in soup.findAll("span",{"class":"label fullname"}):
   userfile.write(span.find("a").attrs[2][1] + "\n")
userfile.close()

 BeautifulSoupにおいて、ポイントは二つです。まず一つにBeautifulSoupを初期化してインスタンスを渡すときに、文字列を引数として使うということ。

 また、soup.findAll(すべての該当するタグを配列で渡す)メソッド、あるいは一番最初の要素だけ取り出すfindメソッドを使う場合に、一番目にタグの指定、そして二番目に属性を指定することが可能です。もちろん、あるクラスの名前がついたものを取り出すこともできます。ドキュメントや解説は、下のサイトを見るとわかりやすいかもしれません。

 BeautifulSoupでスクレイピングのまとめ – taichino.com

 Beautiful Soup: We called him Tortoise because he taught us.

 また、RSSパース可能なので、とりあえずこれ使っておけば間違いないかな、と思います。

今日のまとめ

 つまり、urllib or urllib2、またはMechanize、それとBeautifulSoupを使いこなせば、だいたいのデータを取得することが可能になります。この三つを使いこなして、インターネットの世界を効率よく、楽しく漂うお手伝いになるといいな、と思っています。

 |