LoginSignup
22
16

More than 5 years have passed since last update.

requests-html で javasript のページ読みこむよ!

Last updated at Posted at 2018-12-09

最近、requests-html の存在を知ったので、共有したいと思います。
これまで beautifulsoup4 使ってたんですけど、javascript で動的にコンテンツが変わるページだと上手くいきませんでした。
でも、requests-html の README.md 読むと、javascript なページでもスクレイピングできそうな雰囲気あるじゃないですか!
早速やってみたいと思います。

インストール

まずはインストールから。
mac 使ってるんですけど、Mojave にしてしまったので、pyenv でこんなエラー出ました。

zipimport.ZipImportError: can't decompress data; zlib not available

そんなときは、こうじゃ!

sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /

参考:[MacOS Mojave]pyenvでpythonのインストールがzlibエラーで失敗した時の対応

で、python3.6 でしか動かないって言ってるので、python3.6.7 とか入れてインストールします。

pyenv install 3.6.7
pipenv --python 3.6.7
pipenv install requests-html

そして実行環境立ち上げ。

pipenv shell

試してみる

steam のソフトの情報を取ってきたいと思います。

from requests_html import HTMLSession
session = HTMLSession()
r = session.get('https://store.steampowered.com/search/?sort_by=Released_DESC&os=win')
r.html.render()

[W:pyppeteer.chromium_downloader] start chromium download.
Download may take a few minutes.
100%|███████████████████████████████████████████████████████████████████████| 84299992/84299992 [00:14<00:00, 5986762.94it/s]
[W:pyppeteer.chromium_downloader]
chromium download done.
[W:pyppeteer.chromium_downloader] chromium extracted to: /Users/hoge/Library/Application Support/pyppeteer/local-chromium/575458

初回はレンダリングのためのブラウザをダウンロードします。
で、ソフトのタイトルを表示させたいと思います。

for t in r.html.find('.title'):
    t.text

'永冻之壳 The Shell of Permafrost'
'The Lost Legends of Redwall: Escape the Gloomer Demo'
'Incubo Demo'
'Monsters & Anomaly'
'Elementary Arithmetic Game'
'Samozbor: Rebellion'
'Sumo'
'Slime-san: Creator'
'Black And Blue'
"Hunter's Trial: The fight never ends"
'Thick Light 3'
'ZDF History 360° – Tempelhof'
'Nya Nya Nya Girls (ʻʻʻ)_(=^・ω・^=)_(ʻʻʻ)'
'Ball Out'
'Island Invasion'
'Forex Trading Master: Simulator'
'WWII英雄列伝 最強の虎\u3000クルト・クニスペル Demo'
"Otiiz's adventure - Sushi Champ Demo"
'Adventure Boy Cheapskate DX'
'Iridescence'
'Warhalla'
'Hentai Square Puzzle'
'Black Annex'
'Proto-G Demo'
'Escape Velocity'

おー、きたきた。
ちなみに、beautifulsoup だとこうなります。

import urllib.request, urllib.error
from bs4 import BeautifulSoup
html = urllib.request.urlopen(url='https://store.steampowered.com/search/?sort_by=Released_DESC&os=win')
soup = BeautifulSoup(html, "html.parser")
for t in soup.select('.title'):
    t.text

'永冻之壳 The Shell of Permafrost'
'The Lost Legends of Redwall: Escape the Gloomer Demo'
'Incubo Demo'
'Monsters & Anomaly'
'Elementary Arithmetic Game'
'Samozbor: Rebellion'
'Sumo'
'Slime-san: Creator'
'Black And Blue'
"Hunter's Trial: The fight never ends"
'Thick Light 3'
'ZDF History 360° – Tempelhof'
'Nya Nya Nya Girls (ʻʻʻ)_(=^・ω・^=)_(ʻʻʻ)'
'Ball Out'
'Island Invasion'
'Forex Trading Master: Simulator'
'WWII英雄列伝 最強の虎\u3000クルト・クニスペル Demo'
"Otiiz's adventure - Sushi Champ Demo"
'Adventure Boy Cheapskate DX'
'Iridescence'
'Warhalla'
'Hentai Square Puzzle'
'Black Annex'
'Proto-G Demo'
'Escape Velocity'

・・・・・・・・あれ、見れる(・_・;)

もう一度

もうちょっとレンダリングに時間かかりそうなページにする必要があるっぽいです。
ので、先程は検索結果の1ページ目を使いましたけど、次は後の方(1000ページ目とか)にしてみたいと思います。
まずは requests-html。

session = HTMLSession()
r = session.get('https://store.steampowered.com/search/?sort_by=Released_DESC&page=1914&os=win')
r.html.render()
for t in r.html.find('.title'):
    t.text

'AstroPop Deluxe'
'Big Money! Deluxe'
'Iggle Pop Deluxe'
'Rocket Mania Deluxe'
'Hammer Heads Deluxe'
'Dynomite Deluxe'
'Talismania Deluxe'
'Pizza Frenzy Deluxe'
'Typer Shark! Deluxe'
'Heavy Weapon Deluxe'
'Xpand Rally'
'Uplink'
'Iron Warriors: T - 72 Tank Command'
'X3: Reunion'
'X2: The Threat'
'The Ship: Murder Party'
"Disciples II: Gallean's Return"
'Disciples II: Rise of the Elves'
'Jagged Alliance 2 Gold'
'Half-Life 2: Episode One'
'SiN Episodes: Emergence'
'Shadowgrounds'
'Half-Life Deathmatch: Source'
'Shadowgrounds Demo'
'Earth 2160'

次は beautifulsoup。

html = urllib.request.urlopen(url='https://store.steampowered.com/search/?sort_by=Released_DESC&page=1914&os=win')
soup = BeautifulSoup(html, "html.parser")
for t in soup.select('.title'):
    t.text

お、何も出てこない!
ということは、javascript はレンダリングされてない!(たぶん)

まとめ

  • requests-html 使うとスクレイピングが捗るよ

ちなみに、beautifulsoup でも chromium と wait で頑張れば javascript のページのスクレイピングできたと思います(昔、やった気がする)。
まぁでも requests-html 使うと簡単に実装できそうなので、今後はこっちを使うのが良いと思いました。

22
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
16