Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

最近、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 使うと簡単に実装できそうなので、今後はこっちを使うのが良いと思いました。

ukisoft
まったり developer です。python と js を使うことが多いです。
rymansat
普段は宇宙開発に関わっていないサラリーマンが身近で誰でもできる宇宙開発を実現させることがリーマンサット・プロジェクト(Ryman Sat Project=rsp.)の目的です。キューブサットの開発をはじめ、宇宙を軸として様々なコミュニティやクリエイターとコラボレーションし、民間宇宙開発に関するネットワークを強化、拡張することを目指して活動しています。
https://www.rymansat.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした