ひよこになりたい

Security CTF Programming Server Network and so on

Python+Selenium+Phantom.js+Beautifulsoupでスクレイピングする

最近スクレイピングスクリプト書いて遊んでいるのでそれについてのメモがてらに。

Pythonスクレイピングする方法は多々あるみたいなんですが,個人的に一番使いやすかった(慣れ?)のがこの組み合わせでした。

以前Pythonのurllib.request+Beautifulsoupでレスポンスhtmlの解析をして次々とたどっていくようなスクリプトを書いていたんですが、これだとJavascriptで追加されたエレメントは受け取れなかったり、リダイレクト処理がめっちゃ大変だったり色々と面倒でしたが今回SeleniumとPhantomjsを使用することでその辺りの面倒な処理を一括でできるようになりました。

簡単に流れを説明すると、PythonSeleniumを操作し、SeleniumがPhantom.jsでJSを実行し、結果のHTMLをBeautifulSoupでパースし、解析していきます。

Selenium

Seleniumはブラウザの自動化を行うツールです。複数のブラウザでWebのテストを実行したりすることができたり、Android/iOSでテスト出来たりいろいろと便利(Seleniumサーバー建てて集中管理したりもできるみたいだし)。今回はFirefoxChromeの代わりにPhantom.jsを使います。
Selenium - Web Browser Automation

Phantom.js

Phantom.jsは本来はブラウザがないと実行できないJavascriptを、ブラウザ画面なしで実行できるすごいやつ。API形式で叩けるっぽい? PhantomJS | PhantomJS

Beautiful soup

Beautiful soupはHTML/XMLのパーサーで、HTMLを解析して使いやすくしてくれるものです。HTMLをDOMに倣って列挙したり検索したり選択したりできます。
Beautiful Soup: We called him Tortoise because he taught us.

環境設定とか

特にそんなにすることないけど・・・
使用した言語はPython3.4です。Linux, Mac, Windowsで動くのを確認

Python3は入ってること前提で。まずはpythonseleniumモジュールのインストール

pip3 install selenium

次にPhantom.jsを入れます。これは特に説明しないので適当に入れてください。 http://phantomjs.org/
ちゃんとパスを通しておくこと。

最後にBeautifulSoupを入れます。bsはpython3の場合は2to3コマンドでpython3用に変換する必要があります(公式でそう書いてある)。
http://www.crummy.com/software/BeautifulSoup/#DownloadここからBeautiful Soup 4を落としてきて2to3で変換。

wget http://www.crummy.com/software/BeautifulSoup/bs4/download/4.3/beautifulsoup4-4.3.2.tar.gz  # 現時点(2015/04/12)での最新版
tar zxf beautifulsoup4-4.3.2.tar.gz
cd ./beautifulsoup4-4.3.2
2to3 -w bs4
python3 setup.py

うまく行かなければ2to3した後に直接ライブラリディレクトリの中に突っ込んでもOK

使ってみる

from selenium import webdriver
from bs4 import BeautifulSoup

driver = webdriver.PhantomJS()
driver.get("http://sukumizu.moe/")
data = driver.page_source.encode('utf-8')

print(data)
driver.save_screenshot("ss.png")

driver.quit()

結果

b'<!DOCTYPE html><html><head>\n\t<title>sukumizu.moe</title>\n\t<link rel="st(略

こんなかんじで扱えます。
スクリーンショットも撮れます。

UAを指定したい場合はこんな感じ。以下はChromeの例

from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

des_cap = dict(DesiredCapabilities.PHANTOMJS)
des_cap["phantomjs.page.settings.userAgent"] = (
    'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) '
    'Chrome/28.0.1500.52 Safari/537.36'
)
driver = webdriver.PhantomJS(desired_capabilities=des_cap)
driver.get("http://sukumizu.moe/")
data = driver.page_source.encode('utf-8')

取得したhtmlの解析 (Beautiful soup)

from bs4 import BeautifulSoup

# ----- 略 -----

html = BeautifulSoup(data)
print(html)  # htmlソースを表示する

print(html.title)  # タイトルタグ

print(html.title.string)  # タイトルタグ内の文字

print(html.find('h1'))  # h1タグ

print(html.find_all('link'))  # 全てのlinkタグのリスト

print(html.find_all('link', attrs={'href': 'style.css'}))  # linkタグかつhrefがstyle.cssのもののリスト

結果

<!DOCTYPE html>
<html><head>
<title>sukumizu.moe</title>
---(略)---
</body></html>

<title>sukumizu.moe</title>

sukumizu.moe

<h1>What is your favorite "sukumizu"...? </h1>

[<link ...., <link ...., <link ....]

[<link href="style.css" rel="stylesheet"></link>]

これくらい使えれば困らないかも。他にもいろいろあるのでbsのドキュメントを参照。

タグの要素の選択やチェックはブラウザ標準の「要素を検証」「開発ツール」が便利。 Chromeなら左上の虫眼鏡、Firefoxなら右上の矢印で要素の選択ができます

pythonは簡単でいいなあ