1. Beautiful Soup でデータを取得
気象庁の過去のデータから、特定の値を抽出したい。
においては、ブラウザ上でコピーした文字列 (データ) を、Python のソースコードに貼り付け、必要なデータを抽出した。
今回は、Python で Web にアクセスし、必要なデータを抽出してみる。
Python では、urllib2 を利用すると、 HTTP の POST メソッドを送信することができる。
ただし、urllib2 を使うのは面倒。代わりに、
を利用する。
2. スクレイピングとは
スクレイピングという言葉は、Ruby の scRUBYt! で知った。
スクレイピングとは - はてなダイアリー によると、
英語で"scrape"とは「削ること」。
特に、ウェブサイトのデータを必要な部分だけ抽出して利用すること。
Python では、先ほどの Beautiful Soup が有名なようだ。
Beautiful Soup documentation によると、
Beautiful Soup is an HTML/XML parser for Python that can turn even invalid markup into a parse tree. It provides simple, idiomatic ways of navigating, searching, and modifying the parse tree. It commonly saves programmers hours or days of work.
Beautiful Soup は、HTML/XML パーサで、解析木を作ってくれる。
Ruby 版もあるけれど、hpricot を使うことが推奨されている。
Note: Rubyful Soup is no longer being maintained. I recommend you use hpricot instead.
3. 試してみる
Beautiful Soup を使うために、ソースコードを保存するディレクトリと同じ場所に、BeautifulSoup.py を置いた。
課題は、
「2008 年 1 月の東京の日ごと」の気象データが掲載されているページから、特定の観測対象のデータのみを抽出したい。ただし、抽出するとき、抽出データを後で表計算に貼り付けるため、「タブ区切り」にすること。対象の項目は、「現地の気圧」と「平均気温」とする。
スクレイピングの対象である HTML の構造を調べるために、Firefox のプラグインである Firebug を使う。調べた結果、タグと CSS を使った指定により、目的の要素を取得できそうだった。
HTML の要素を辿るには、
for 変数 in BeautifulSoupオブジェクト('タグ', {'属性':'値'}):
これにより、目的の要素を取得する。
from BeautifulSoup import BeautifulSoup import urllib2 # 対象のアドレス URL = "http://www.data.jma.go.jp/obd/stats/etrn/view/daily_s1.php?prec_no=44&prec_ch=%93%8C%8B%9E%93s&block_no=47662&block_ch=%93%8C%8B%9E&year=2008&month=01&day=12&view=p1" # 出力する日付 DATE_FROM = 1 DATE_TO = 5 # Web からデータを取得する html = urllib2.urlopen(URL).read() soup = BeautifulSoup(html) records = [] # class 属性が mtx である tr タグを対象に for tr in soup('tr', {'class':'mtx'}): rec = [] # id 属性が p_print の div タグを対象に for div in tr('div', {'id':'a_print'}): # a タグを対象に for a in div('a'): # 日付を取得 rec.append(a.renderContents()) # class 属性が data_0_0 である td タグを対象に for td in tr('td', {'class':'data_0_0'}): # 各データを取得 data = td.renderContents().strip() rec.append(data) if rec != []: records.append(rec) # 取得したデータを出力する for rec in records: # 指定された日付の期間以外は出力しない。 if int(rec[0]) not in range(DATE_FROM, DATE_TO + 1): continue for i, data in enumerate(rec): if i in [1,6]: print unicode(data, 'utf-8'), "\t", print
データを取得したいページのアドレスを設定し、取得したい日付の期間を入力すると、日ごとの気圧と気温のデータを抽出することができる。
参考
- Panopticon :: Python :: BeautifulSoupを触ってみる
- BeautifulSoupでHTML解析 - Perl使いのPythonちゃん
- WeekBuildのHACK日記 UnicodeとUTF-8の違い
0コメント:
コメントを投稿