MENTAの自動化系の相談でよく「requestsで情報が取得できない非同期処理のサイトやSeleniumでログインが必要なサイトをスクレイピングして情報を取得したい時はどうすればよいですが」という質問を受けるので、テンプレ回答としてメモしておきます。
SeleniumとBeautifulSoupを組み合わせた方が良い時
Udemyとかの講座でよくある基本的なスクレイピングの流れはrequestsでサイトでhtmlを取得してBeautifulSoupで解析するみたいな感じですが、スクレイピングの需要のあるサイトは大抵非同期処理を使っていたりログイン必須のサイトなので、requests.get()ではうまくhtmlを取得出来ないときが多いです。
こういう時は使われるのがSeleniumで、非同期で送られてくる情報を取得したい場合はSeleniumでサイトにアクセスして一定時間が経過後にseleniumが読み込んでいるページソースを取得して、それをBeauifulSoupで解析したほうがセッションとかasyncを使わなくてよいので手っ取り早いです。
非同期処理とは
非同期処理とは、一つのタスクを実行中であっても他のタスクを実行できる実行方式をいいます。非同期処理をうまく実装することで、ユーザーはアプリケーションの処理待ちを気にすることなくアクセスすることができるため、ユーザビリティを考えるうえで重要な要素になります。
ようはウェブサイトが表示された後から情報を読み込みこむ技術です。これがスクレイピングにおいて何が面倒なのかというと非同期処理の情報はサイトの情報が読み込まれた後から送られてくるのでrequests.get()などで安直にURLを叩くと非同期処理の情報が載っていないHTMLがレスポンスに返ってくるのでスクレイピングしても欲しい情報がなかったりします。
特に非同期処理はECサイトの商品情報を表示させる際によく使われており、例えばAmazonなんかだとブラウザで表示されているURLをrequests.get()で取得しても、商品情報は非同期処理であとからサイト送られてくるので、最初のHTTPリクエストの時点ではまだ存在しておらず、requests.get()の返り値には商品情報がないサイトの外側の部分のHTMLだけが返されます。
サンプルコード
以下に実際にseleniumとBeauifulSoupを組み合わせたサンプルコードを乗せておきます。
流れとしてはSeleniumで対象のwebサイトにアクセスし、サイトの非同期処理のデータが表示された状態になったら、driver.page_sourceでSeleniumで表示されているサイトのHTMLを取得しBeautifulSoupで変換して解析できるようにします。
import time from selenium import webdriver ~~~ (ライブラリの読み込みとか基本設定は環境で代わるので省略) ~~~ # SELENIUMでサイトにアクセス driver.get("http://~~~") # 非同期処理の情報が表示されるまで待機 time.sleep(5) # Seleniumのブラウザが表示しているサイトのHTMLを取得 html = driver.page_source # 取得したHTMLをBeautifulSoupで解析できろようにする from bs4 import BeautifulSoup soup = BeautifulSoup(html)
あとはこれで普通にBeautifulSoupで解析するだけです。
# 非同期処理で表示されるtableタグの情報が欲しい時(例) table_data = soup.find_all('table')
参考書籍
コメント
[…] 関連記事:requestsでhtmlが取得できないWebサイトをSeleniumでスクレイピングする […]
[…] 関連記事:requestsでhtmlが取得できないWebサイトをSeleniumでスクレイピングする […]