ひよこになりたい

Programming Server Network Security CTF and so on

Python+Selenium+Chrome(+BeautifulSoup)でスクレイピングする

以前Python+Selenium+Phantom.js+Beautifulsoupでスクレイピングする - ひよこになりたいという記事を書きました。

zipsan.hatenablog.jp

当時はChromeを入れる必要がなく、バイナリを置くだけで使えるPhantom.jsが非常に便利でこれを使っていたのですが、去年、Phantom.jsのメンテナンスが終了するというニュースが発信され、記事も書き換えないとなあと思っていました。が、それから暫くの間はJavascriptをリアルタイム処理させる必要のないページばかりスクレイピングしていたので、結局放置したままでした(すみません)。

ここ1年の間に、ChromeのVersion59以降より標準で(stable版で)headlessモード(ブラウザ画面が立ち上がらないモード)が使えるようになったらしく、前のようにxvfbのような仮想スクリーンを使う必要もなくなったことに加え、久々にJavascriptが必要なサイトをスクレイピングする必要が出てきたため、この機会に使用法についてまとめておくことにします。

Phantom.jsの作者さんもChromeを使うとよろしーと言っているみたいですね。

環境構築

必要なもの

  • Python + pip(ここでは3.6.5を使いました)
  • Selenium
  • Google Chrome(Version59以上だったらOKです。)
  • ChromeDriver

OSはLinuxでもMacでも大丈夫です。多分Windowsでもいけます。私はArch Linux(GUIなし)を使いました。

インストール

  • Python+pip
    • 適当に入れておいてください
  • Selenium
    • pip install seleniumでインストール出来ます。
  • Google Chrome
    • Package管理ツールでいれてもいいですし、exeやdmg、直接rpmdebからいれてもいいです。
    • CentOSだったら CentOS7にChromeをインストール - Qiita あたりが参考になるかと思います。
    • Arch Linuxの場合は yaourt -S google-chrome-stable で入れれます。(私の場合はライブラリの依存関係が壊れていたので、起動時のエラーを見ながらdowngrade で頑張って3-4個のライブラリをダウングレードして起動まで持っていきました)
  • Chrome Driver
    • Downloads - ChromeDriver - WebDriver for Chrome からダウンロード出来ます。
    • ダウンロードして解凍しましょう。多分中にchromedriverというバイナリがあるはずです。適当なディレクトリに移動してておき、パスを通しておきましょう。
      • echo 'export PATH="$PATH:/path/to/chromedriver_directory"' >> ~/.bashrcとかで行けるんじゃないかなあ(未検証)

使ってみる

# -*- coding: utf-8 -*-
from selenium import webdriver

options = webdriver.chrome.options.Options()
options.add_argument("--headless")  # これ消せばブラウザ画面が出ます

driver = webdriver.Chrome(chrome_options=options)

driver.get("https://sukumizu.moe")

# タイトル
print(driver.title)

# URL
print(driver.current_url)

# cookies
print(driver.get_cookies())

# スクリーンショットの撮影
print(driver.save_screenshot("screenshot.png"))

# ページのソースの取得
print(driver.page_source)

Phantom.jsのときのように一通り欲しい機能は揃っていますね。

また、driver.page_sourceをBeautifulSoupに食わせれば以前のようにそのままBeautifulSoupの機能が使えますし、Seleniumにはそもそも要素の選択機能があるので、それを使ってスクレイピングすることも出来ます。

# id検索
driver.find_element_by_id('id')

# class検索
driver.find_element_by_class_name('classname')

# ネストされた要素の取得
driver.find_elements_by_xpath(".//div")

7. WebDriver API — Selenium Python Bindings 2 documentation

また、クリックや文字入力もできるので、もうなんでもやりたい放題って感じです。

UI操作はちょっと複雑なコードになるのでここでは割愛します。興味がある方は調べてみてください。