[Python] JavascriptでレンダリングされるWebページを、スクレイピングする
こんにちは、@yoheiMuneです。
今日はReact.jsなどのJavascriptでページをレンダリングするページについて、スクレイピングを行う方法をブログに書きたいと思います。
 
 http://yoheim.net/work/async_page.html
http://yoheim.net/work/async_page.html
上記のページでは以下のようなJSで、ページ表示時に画像を動的に読み込みます。
 http://phantomjs.org/
http://phantomjs.org/
ダウンロードしてきたファイルを、例えば以下のようにすることで、パスを通すことができます。
最後に以下のコマンドが動けばOKです。
最後になりますが本ブログでは、Python・Linux・Node.js・フロントエンド・インフラ・Go言語・開発関連・Swift・Java・機械学習など雑多に情報発信をしていきます。自分の第2の脳にすべく、情報をブログに貯めています。気になった方は、本ブログのRSSやTwitterをフォローして頂けると幸いです ^ ^。
最後までご覧頂きましてありがとうございました!
今日はReact.jsなどのJavascriptでページをレンダリングするページについて、スクレイピングを行う方法をブログに書きたいと思います。
 
目次
スクレイピング対象のページ
今回は以下のJavaScriptで、画像を追加して表示するようなページを対象にします。 http://yoheim.net/work/async_page.html
http://yoheim.net/work/async_page.html上記のページでは以下のようなJSで、ページ表示時に画像を動的に読み込みます。
<ul id="imageRoot">
    <li>ここにJavaScriptでレンダリングします.</li>
</ul>
<script>
window.addEventListener('DOMContentLoaded', function() {
    urls = [
        '//yoheim.net/image/s156.png',
        '//yoheim.net/image/s157.png',
        '//yoheim.net/image/s158.png'
    ];
    var ul = document.getElementById('imageRoot');
    ul.innerHTML = '';
    urls.forEach(function(url) {
        var image = new Image();
        image.src = url;
        ul.appendChild(image);
    });
});
</script>
そのためurllib.requestなどで単純にHTMLを取得しただけだとダメで、Javascriptを評価して実行する必要があります。準備
JSの実行も含めてスクレイピングを行うために、以下の3つの技術要素を利用します。- BeautifulSoup
- スクレイピングライブラリ
- PhantomJS
- ヘッドレスブラウザ
- Selenium
- ブラウザの自動操作を行うツール
BeautifulSoupのインストール
BeautifulSoupはpipで導入することができます。$ pip install --upgrade beautifulsoup4
PhantomJSのインストール
PhantomJSは以下のサイトから実行ファイルをダウンロードして、そのファイルにパスを通すことで動かせるようにします。 http://phantomjs.org/
http://phantomjs.org/ダウンロードしてきたファイルを、例えば以下のようにすることで、パスを通すことができます。
# ダウンロードしてきたディレクトリに移動 # 以下の場合は、Downloadフォルダにある例です cd ~/Downloads/phantomjs-2.1.1-macosx/ # /usr/local/bin にコピー cp bin/phantomjs /usr/local/bin/もしくは
~/.bash_profileなどでパスを通すのでも良いです。お好みの方法でパスを通してください。最後に以下のコマンドが動けばOKです。
$ phantomjs phantomjs>
Selenimのインストール
Seleniumはpipからインストールすることができます。$ pip install --upgrade selenium以上で準備は完了です。
JSでレンダリングするページをスクレイピングする
やっと本題です。JSレンダリングを含めてスクレイピングする場合には、以下のように実装します。
from pprint import pprint
from selenium import webdriver
from bs4 import BeautifulSoup
import time
# PhantomJSをSelenium経由で利用します.
driver = webdriver.PhantomJS()
# PhantomJSで該当ページを取得&レンダリングします
driver.get("http://yoheim.net/work/async_page.html")
# ちょっと待つ
# (ページのJS実行に時間が必要あれば)
# time.sleep(5) # 5s
# レンダリング結果をPhantomJSから取得します.
html = driver.page_source
# 画像のURLを取得する(JSでレンダリングしたところ).
bs = BeautifulSoup(html, "html.parser")
img_urls = [img.get("src") for img in bs.select("#imageRoot img")]
pprint(img_urls)
# ついでにスクリーンショットも取れます.
driver.save_screenshot("ss.png")
# 終了
driver.quit()
とこんな感じでデータを取得できます。実装自体はシンプルでいいですね!最後に
Javascriptの実行結果をスクレイピングできると、より多くのサイトのデータを取得できるので楽しい限りです。Pythonについてはまだまだいっぱいブログを書こうと思います。最後になりますが本ブログでは、Python・Linux・Node.js・フロントエンド・インフラ・Go言語・開発関連・Swift・Java・機械学習など雑多に情報発信をしていきます。自分の第2の脳にすべく、情報をブログに貯めています。気になった方は、本ブログのRSSやTwitterをフォローして頂けると幸いです ^ ^。
最後までご覧頂きましてありがとうございました!
 
  
