このところ、スクレイピングの調べ物が多いです。
実際、本で紹介されていたモジュールで、面白いものがあったので、簡単に紹介します。
読んだ本
PythonでWebリクエストを投げる
これは、標準モジュールはあまり使わず、requests
モジュールを使うことが多いです。
単純なGET
リクエストなら、
import requests
res = requests.get(url)
だけで実行できます。
セッションの維持が必要になる場合も、
import requests s = requests.Session() s.auth = ('user', 'pass') s.headers.update({'x-test': 'true'}) # both 'x-test' and 'x-test2' are sent s.get('http://httpbin.org/headers', headers={'x-test2': 'true'})
のような感じで、わりと簡単に書けます。
作成したSession
オブジェクトを使って、リクエストを実行し続ければいいだけです。
ソースコードはRequests
モジュールのヘルプから取得しています。
リクエスト結果を解釈する
GET
リクエストを、通常の、普段私たちが見るWebページのURLに対して実行したら、返ってくるのはHTML
です。
スクレイピングは、すごく簡単に言うと、返ってきたHTML
の中身を検索して情報を取り出す作業です。
それを簡略化するのがlxml
モジュールです。
英語しかないですが、雰囲気で読みましょう。
解釈だけならそこまで難しくないです。
要素を取る
XPath
で指定すると楽です。
import requests import lxml.html # HTMLソースを得る url = "http://~~~" r = requests.get(url) html = r.text # HTMLをHtmlElementオブジェクトにする root = lxml.html.fromstring(html) # XPathを指定して該当する要素のリストを得る titleH1 = root.xpath("//*[@id=\"cx_contents_block\"]/div/section/h1") # リストの1番目のテキストを表示する print(titleH1[0].text)
相対パスを使ってのアクセスも、一度要素を取ってしまえば可能です。
import requests import lxml.html # HTMLソースを得る url = "http://~~~" r = requests.get(url) html = r.text # HTMLをHtmlElementオブジェクトにする root = lxml.html.fromstring(html) path = "//*[@id=\"cx_contents_block\"]/div/section/div/div[2]/dl" dl = root.xpath(path) # itemprop属性がある要素だけ抽出する relation_path = ".//*[@itemprop]" pub = dl[0].xpath(relation_path)
要素のループ
path = "//*[@id=\"cx_contents_block\"]/div/section/div/div[2]/dl" dl = root.xpath(path)
の後、
relation_path = ".//*[@itemprop]" pub = dl[0].xpath(relation_path)
と、dl[0]
で要素にアクセスしているのですが、これは、xpath
の戻り値がlist
であるためです。
取得した要素全てに対して処理したい場合、単に
for p in pubs: print(p)
のように、for
ループするだけでいいです。
属性の取得
先ほどの続きです。
pub = dl[0].xpath(relation_path) for prop in pub: # 書籍情報を取得する item_prop = prop.attrib.get("itemprop")
上のように、attrib
を使うと、属性にアクセスできます。
attrib
自体はlxml
の独自型ですが、辞書(dict
)と同じ感じでアクセスできます。
他の機能
上で書いた本には紹介されているのですが、HTML
を構築する機能もあるようです。*1
おわりに
今回、薄味ですみません。
私が準備している、別の勉強会のネタを流用して、この記事は作られました。
スクレイピング自体は、やってみるとなかなか楽しいですし、情報の収集としては現実的な手法です。
知っておいて損はない、と思っています。
まあ、scrapy
使えばいいんじゃね?という話になるのですが、簡単なものなら本当にすぐ作れる、というのが事実です。
ではまた。
*1:フィードを作る、という内容。etreeというクラスが用意されている