Python + Seleniumで、無限スクロールの Web ページを最下部までスクロールする方法を紹介します。
スポンサーリンク
無限スクロールって何?
スクロールしないと、続きのコンテンツが表示されないページに出会った方は多いでしょう。
特に写真などを表示するギャラリーサイトなどで無限スクロールは多く採用されており、Google フォトなどがまさに無限スクロール方式を採用しています。このように、ユーザーが画面を下までスクロールすることで、新しい情報を自動で読み込むUI方式のことを「無限スクロール」と呼びます。
無限スクロールのサイトをスクレイピング するのは少しやっかいで、まず コードで表示するコンテンツが無くなるまでスクロールをさせる処理を行った後、読み込んだ全体の HTML をスクレイピング する手順を踏みます。
実際にスクロールさせてみよう!
サンプルコードを紹介する前に、無限スクロールのサイトをスクロールしていくポイントを解説します。
無限スクロールのページは、画面を下までスクロールさせることで続きのコンテンツが表示されるわけだが、一気にページの最下部までスクロールを行なってしまうと、途中のコンテンツの読み込みを飛ばしてしまう恐れがあるため、次のイメージのとおり、ブラウザの高さの 80% ずつページをスクロールしていくようにする。
さらに、無限スクロールはスクロール一定のところまで下がると、JavaSciprt 等で次のコンテンツのロードが行われるため、こちらもスクロールを行うたびに 0.5 秒程度の待機を行い、次のコンテンツの読み込みを待機する。
前置きが長くなってしまったが、Selenium で読み込んだページを、上のイメージのように Python のコードでスクロールしていくサンプルコードを紹介する。詳細な処理内容については、コード上のコメントを見て頂きたい。
url = "https://xxxxxxxxxxxxxxxxxxxxxxxxx/"
#ブラウザのウインドウ高を取得する
win_height = driver.execute_script("return window.innerHeight")
#スクロール開始位置の初期値(ページの先頭からスクロールを開始する)
last_top = 1
#ページの最下部までスクロールする無限ループ
while True:
#スクロール前のページの高さを取得
last_height = driver.execute_script("return document.body.scrollHeight")
#スクロール開始位置を設定
top = last_top
#ページ最下部まで、徐々にスクロールしていく
while top < last_height:
top += int(win_height * 0.8)
driver.execute_script("window.scrollTo(0, %d)" % top)
time.sleep(0.5)
#1秒待って、スクロール後のページの高さを取得する
time.sleep(1)
new_last_height = driver.execute_script("return document.body.scrollHeight")
#スクロール前後でページの高さに変化がなくなったら無限スクロール終了とみなしてループを抜ける
if last_height == new_last_height:
break
#次のループのスクロール開始位置を設定
last_top = last_height
動作イメージ
Web デザインのギャラリーサイトである「MUUUUU.ORG」で、実際に上で紹介したコードを実行してスクロールさせてみた様子を GIF 動画にしてみました。
うん!! いい感じにスクロールが徐々に行われ、ページの下の方までくると自動で次のコンテンツが読み込まれていますね!
スポンサーリンク
まとめ
Python + Seleniumで、無限スクロールのページを自動スクロールする方法を解説しました。
最近は、スクロールしないと続きのコンテンツが表示されないサイトが増えてきたので、これはかなり重宝するでしょう!
こんにちは!javascriptを使ってウィンドウをスクロールすることで悩んでいたのでとても重宝しました!ありがとうございます。
返信削除ところでちょっとだけ分からないのですがウィンドウサイズを取得して、その値に0.8を掛けてますよね?なぜ0.8なのですか?
すみません。自己解決というか記事を全文読んでませんでした。コードの部分だけみて、はて?となっていたので質問してしまいました。
削除有用な情報をありがとうございました。
お役に立てたようで、嬉しいです。
削除これ実行すると
返信削除'NameError: name 'time' is not defined'
って出ますね。