徒然理系日記

日々の備忘録と日記

MENU

Pythonを使ったスクレイピングでWebページの情報を取得しようとすると処理が終わらない問題について ~動的サイトのスクレイピング~

はじめに

Pythonによるスクレイピングを行おうとしていた時に生じた問題とその解決策について、メモも兼ねて記録を残しておこうと思います。結論から言うと、生じた問題は「『動的サイト』をスクレイピングするときは『静的サイト』をスクレイピングするときとは同じ方法ではうまくいかない」ことに起因していました。しかし、この原因を発見するのにもかなり苦労してしまったので、同じようなトラブルに見舞われている方がいれば力になれるかと思い、記事にします。

やろうとしていたこと

Seleniumを使ってWebページへのアクセス・操作をしたのちにBeautifulSoupとRequestsを使ってページのHTMLから情報を取得しようと思っていました。実際Pythonを使ったスクレイピングをされたことのある方はイメージがつくかもしれませんが、以下のようなコードでこれを実行しました。

〜
path = "C:\\Users\\hogehoge\\chromedriver.exe"                                  
driver = webdriver.Chrome(executable_path=path)            
current_url = driver.current_url                                             
res = requests.get(current_url)                                 
soup = BeautifulSoup(res.text, "html.parser")                          

# この後にHTML中でほしい情報を取得するようなコードが続きます
〜

生じた問題と解決までの軌跡

上記のコードは複数のサイトで問題なく動いていたものの、あるサイトで試そうとしたところ「プログラムがタイムアウトする」「処理が終わらない」といったトラブルに見舞われてしまいました。そこで、一つ一つ問題を切り分け、原因を探っていくことにしました。

Step1

あるサイトで上記のコードを試そうとしたところ、どう頑張ってもSeleniumタイムアウトしてしまった。
→どうやらSeleniumがURL取得できていない模様。

Step2

SeleniumでのURL取得に問題があると考え、Seleniumでのページ遷移・URL取得を行わずに直接URLを指定してみた。(下記コード)

〜
url = "http://www.fugafuga"              
res = requests.get(url)                                 
soup = BeautifulSoup(res.text, "html.parser")       
〜

→これでもまた処理が終わる気配なし。

Step3

同じようなトラブルに見舞われている人がいないかと思い、インターネットに頼ることに。そこで見つけた下記のサイトを参考に、requests-htmlというライブラリを検討。

参考にしたサイト

gammasoft.jp
yuki.world

書いたコードはこちら。

〜
session = HTMLSession()
r = session.get(url)
r.html.render()  
〜

→これもまた、処理が終わらず…
ただ、先ほどのサイトから、スクレイピング対象としているサイトが「ダウンロードしたHTMLファイル」と「ブラウザに表示されるHTML」が異なる「動的サイト」である可能性に思い当たりました。

Step4

URL経由でダウンロードしたHTMLファイルとブラウザに表示されるHTMLが異なっているのであれば、ブラウザから直接HTMLのソースを持ってこれれば良いのでは!?ということに気づき、コードを以下のように改変。

〜
source = driver.page_source                                            
soup = BeautifulSoup(source, "html.parser")                
〜

→ 成功!

まとめ

アクセスした端末や時間帯で内容が変わる「動的サイト」に対してスクレイピングを行うときはURLからHTMLを取得するのではなく、ブラウザに表示されるHTMLのソースを直接取得する方法が有効であることが分かりました。もし、「URL取得の段階で処理が終わらない」「URL取得による収集データと実際にWebページで表示されている内容が違う」などのトラブルに遭った際は、対象としているサイトが動的サイトである可能性があるため、是非こちらの方法を試してみてください。

正直requests-htmlで上手くいかなかった理由はあまりよく分からないのですが、Seleniumで直接HTMLソースを見に行くこちらの方が直観的に分かりやすいような気がしました。

補足

動的サイトと静的サイトの違いについて分かりやすくまとまっているサイト
pikawaka.com
お恥ずかしながら私は今回の問題に直面するまで動的サイトと静的サイトの名前すら聞いたことがない状態でした…