クリックさせたはずのボタンが、なぜか反応しない。Seleniumで動的なWebアプリのテストを組んだことがある方なら、一度はこの空振りを味わっているはずです。原因を追っていくと、たいていたどり着くのは2つ。対象のボタンがビューポートの外に居座っていたか、あるいはスクロールを引き金に商品が後追いで描画される作りだったか、です。SNSのフィードもECの一覧も、今やこの「動かして初めて見える」設計が当たり前。だからこそ、生身のユーザーが目にしている画面を、テスト側にも忠実に再現できるかどうかが問われます。私自身、Web自動化を長く触ってきて言い切れるのは、Seleniumのスクロールは添え物の機能ではないということ。すぐ壊れる頼りないテストと、本番で踏ん張れる自動化との境界線は、ここに引かれています。
この記事で扱うのは、その境界線をどう越えるかです。スクロールがなぜ無視できないのか、遅延読み込みのリストや画面に貼り付く固定ヘッダーをどう攻略するのか、そしてThunderbitのようなツールが作業をどこまで短縮してくれるのか——実際に動くコードと、ブラウザごとの注意点、現場で痛い目を見て学んだ勘どころを添えて順に解きほぐしていきます。目指すゴールは、テストの気まぐれに付き合うのをやめ、出てきた結果をそのまま信じられる状態です。
Seleniumでのスクロールの基本を理解する
ここでいったん言葉を定義しておきます。Seleniumの文脈で「スクロール」と言ったとき、具体的に何が起きているのでしょうか。要は、ブラウザの表示領域をコードから上下左右、あるいは狙った要素の位置まで動かし、これから触りたいコンテンツを画面上に呼び出す操作のことです。ここで見落とされがちなのが、Selenium WebDriverは放っておいてもスクロールしてくれないという事実。表示範囲の外にある要素にクリックを試みると、あのElementNotInteractableExceptionが顔を出します(GeeksforGeeks)。狙った座標へきっちりスクロールする——この一手が、安定したUIテスト自動化の出発点になるわけです。前提として、本ガイドは終始Selenium 4.x系で話を進めます。ホイール/スクロール入力が登場したのは4.2、そして最新の4.43でも現役の作法です(Selenium downloads)。Selenium 3を使い続けている環境では、Actions APIのコードはそもそもコンパイルが通らないので、記事後半で扱うJavascriptExecutor方式に切り替えてください。
Seleniumで日常的に登場するスクロール操作を、ざっと挙げておきます。
- 縦スクロール: 画面を上下方向へ送り、隠れていた中身を呼び出す。
- 横スクロール: 横幅のある表やカルーセルを扱うときに重宝する。
- 要素までスクロール:
scrollIntoViewなどを使い、狙った要素を画面内へ送り込む。 - ピクセル単位でスクロール: 決まった量だけ刻んで動かす。じわじわ送りたい場面向き。
- ページ先頭/末尾へスクロール: 冒頭や最後尾へ一足飛びに移動する。
そこまで神経を使う理由は、現代のページが動的要素のかたまりだからです。途切れず続く無限スクロール、押すたびに増える「もっと見る」、画面に張り付く固定ヘッダー、視界に入った瞬間に読み込まれる画像——挙げればきりがありません。テストにスクロールの手段がなければ、UIの半分は最初から視界の外。結果として、本来拾えたはずのバグが素通りし、あるいは本筋とは無縁の理由でテストが落ちます(BrowserStack)。
よくある落とし穴:
- 要素を特定できたからといって、それが画面に出ている、あるいは押せる状態だとは限らない。
.click()も.sendKeys()も、要素のところまで勝手にスクロールしてはくれない。- 固定ヘッダーが、スクロールを終えてもなお要素に覆いかぶさることがある。
- 無限スクロール型のページでは、中身を引き出すために小刻みなスクロールを何度も挟む必要がある。
まず押さえておきたい、対象を表示範囲へ送り込む最小限のJavaコードがこちらです。
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element);
これで対象要素がビューポート上部に表示されるので、「要素を操作できない」エラーを防げます。
Seleniumで効率的にスクロールすることがWebテストで重要な理由
身も蓋もない言い方をすれば、今どきのWebアプリは「スクロールして初めて中身が出てくる」構造に乗っかっています。数字を挙げると、jQueryに限定した集計でさえ51万6,000を超える公開サイトが無限スクロールを使っているとされ、実数はこれを大きく上回ると見られています。つまり、一度もスクロールしないテストは、アプリのかなりの領域を最初から検査対象から外しているのと同じことです。
スクロールが必要になる場面:
- 無限スクロール/遅延読み込みリスト: SNSのタイムライン、商品一覧、SaaSのダッシュボードなど。
- 「もっと見る」ボタン: ECサイトやニュースサイト、各種ディレクトリでおなじみ。
- 隠れているボタンやリンク: スクロールして初めて姿を現すたぐいの要素。
- 固定ヘッダー: 要素に覆いかぶさるため、スクロール位置を緻密に調整する必要がある。
- 大きな表やカルーセル: 横方向の送りやコンテナ内でのスクロールを伴うことが多い。
| テストシナリオ | なぜスクロールが必要なのか |
|---|---|
| 無限コンテンツフィード(例: SNS) | スクロールするたびに新しい投稿が読み込まれる。すべての項目を読み込み、検証するには繰り返しスクロールが必要。 |
| 「もっと見る」ページネーション | スクロール/クリックするまで追加項目がDOMに存在しない。 |
| 遅延読み込み画像 | 画像は表示範囲に入ったときにだけ読み込まれる。すべての画像が存在し読み込まれていることを確認するにはスクロールが必要。 |
| 固定ヘッダーがコンテンツに重なる | 要素がヘッダーの下に隠れることがあるため、それを考慮したスクロールが必要。 |
| 大きなスクロール可能テーブル/カルーセル | 一度に表示されるのは一部だけ。すべての行や項目へアクセスして検証するにはスクロールが必要。 |
ROI:
- テストカバレッジの向上: 初期表示の要素にとどまらず、UI全体を検証の網にかけられる。
- 手作業の削減: テストを分割したり、表示のために人手を挟んだりする手間が消える。
- 自動化の信頼性向上: 「要素が見つからない」「触れない」といった偽の失敗が減る。
イメージしやすいように、数字で考えてみます。商品が100点並ぶECサイトで、初回に描画されるのは20点だけ、という設定です。スクロールを使わないテストが触れられるのはカタログのわずか2割、残る8割は検証されないまま放置されます。逆に、効率よくスクロールできれば、より多くのバグをより早い段階で炙り出せるわけです。

スクロールの全手法: Seleniumのスクロール技法を比較する
scrollDown()という一発で済むコマンドはSeleniumに用意されていません。ただ、目的地への道筋自体はいくつも引かれています。ここで全体像を一度見渡しておきましょう。
| 方法 | ブラウザ対応 | 難易度 | 最適な用途 |
|---|---|---|---|
| Actions API(ホイール入力) | Chrome、Edge(Selenium 4) | 中 | ネイティブな、正確な要素までのスクロールやオフセットスクロール |
| JavaScriptExecutor | すべてのブラウザ | 易 | 要素まで、ピクセル単位、ページ先頭/末尾へのスクロール |
| キーボードキー(Page Downなど) | すべてのブラウザ | 易 | ユーザーのキー操作によるスクロールを再現 |
| 要素内スクロール | すべてのブラウザ | 中 | コンテナ、表、カルーセル内のスクロール |
要素までスクロールする方法と、ピクセル単位でスクロールする方法
要素までスクロール:
狙う対象がひとつに絞れている場面で本領を発揮します。
js.executeScript("arguments[0].scrollIntoView();", webElement);
または、Selenium 4のActions API(Chrome/Edge)を使って:
new Actions(driver).scrollToElement(element).perform();
ピクセル単位でスクロール:
じわじわ動かしたいとき、あるいは表示位置をミリ単位で詰めたいときに合います。
js.executeScript("window.scrollBy(0, 350)", "");
正の値で下へ、負の値で上へスクロールします。
使い分けの目安:
- 正確さと安定を取るなら、要素までスクロール。
- 段階的な読み込みやパララックス、人間くさい動きを再現したいなら、ピクセル単位のスクロール。
ページ先頭/末尾へのスクロールと無限スクロールの扱い
末尾へスクロール:
js.executeScript("window.scrollTo(0, document.body.scrollHeight)");
先頭へスクロール:
js.executeScript("window.scrollTo(0, 0)");
無限スクロールの処理:
ここで主役になるのがループです。スクロールしては新しいコンテンツの到着を待ち、追加が止まったところで抜ける——この繰り返しで対応します。
long lastHeight = (Long) js.executeScript("return document.body.scrollHeight");
while (true) {
js.executeScript("window.scrollTo(0, document.body.scrollHeight);");
Thread.sleep(2000); // 実際のテストでは明示的な待機を使いましょう!
long newHeight = (Long) js.executeScript("return document.body.scrollHeight");
if (newHeight == lastHeight) break;
lastHeight = newHeight;
}
このパターンなら、実際のユーザーと同じようにすべてのコンテンツを読み込めます(Testsigma)。
execute_script を使ったSeleniumのカスタムスクロール
定番の操作から一歩踏み込む場面になると、JavaScriptのexecute_scriptが心強い味方になります。具体的には、次のような芸当が可能です。
- 小刻みに送って、人間が操作しているような動きを再現する。
- ひとスクロールごとに、中身が読み込まれるのを待ち受ける。
- 表やカルーセルといった、特定コンテナの内側だけを動かす。
- 固定ヘッダーや動的要素といった、変則的なケースをさばく。
例: なめらかに段階スクロールする
for i in range(10):
driver.execute_script("window.scrollBy(0, 500);")
time.sleep(0.5)
例: スクロール後にコンテンツを待つ
js.executeScript("window.scrollTo(0, document.body.scrollHeight);");
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("new_element")));
ベストプラクティス:
- 送るたびに、明示的待機で新しい中身が出そろうのを必ず待つ。
- 見やすさが必要なら、
scrollIntoViewに{block: "center"}を添える。 - 固定秒数のsleepは禁物。中身の変化そのものに紐づけた待機を使う。
- コンテナ内を動かすときは、JSの
element.scrollTop = ...やelement.scrollBy(...)を用いる。
ブラウザごとにSeleniumのスクロールを最適化する
ここで一段ややこしくなります。スクロールへの対応度合いは、ブラウザによってまちまちだからです。
- Chrome / Edge / その他のChromium系ブラウザ(Brave、Opera、Arc): Actions APIのホイール入力(
scrollToElement、scrollByAmount、scrollFromOrigin)とJavaScriptをフルサポート。 - Firefox: JavaScriptによるスクロールは問題なく動作します。Actions APIのホイール入力はgeckodriverでは未対応です。Seleniumのドキュメントでも、ホイール操作はChromiumのみとされています。代わりに
JavascriptExecutorを使いましょう。 - Safari: Firefoxと同様です。safaridriverはホイールのエンドポイントを実装していません。
JavascriptExecutorとarguments[0].scrollIntoView(...)を使うのが無難です。 - ヘッドレスモード: 明示的にウィンドウサイズを設定してください(
driver.manage().window().setSize(...)、またはChromeなら--window-size=1920,1080)。設定しないとビューポートが小さくなり、通常のブラウザでは画面外に出るコンテンツが遅延読み込みを引き起こさないことがあります。
ヒント:
- スクロール処理は、対象ブラウザすべてで早い段階から動作確認しておく。
- どこでも効く保険として、JavaScriptを用意しておく。
- 固定ヘッダー対策には、数ピクセル多めに送るか、重なりをかわす独自JSを当てる。
- ヘッドレス時は
driver.manage().window().setSize(...)で画面サイズを決め打ちし、挙動を安定させる。
Thunderbit: スマートなスクレイピングでSeleniumのテスト開発を加速する
AIで動的Webデータをスクレイピング Get Started Free
Seleniumの守備範囲はブラウザの操作までで、その先のデータ抽出には踏み込みません。ロケーターもループもアサーションも、結局は自分の手で書き起こす必要があります。もし検証したいページが、商品一覧やSNSのタイムライン、遅延読み込みのテーブルのように動的でスクロール量の多い作りなら、ここでThunderbitが補助ツールとして光ります。ページを渡すだけで、スクロールもページ送りも、構造化データの抽出までまとめて代行してくれるので、その出力をSeleniumテストの照合基準として流用できるわけです。一回限りのスクレイパーをゼロから組むより、テストの「期待値」側をはるかに手早く整えられる近道といえます。
ThunderbitがSeleniumを補完する方法:
- 無限スクロールページごと、データをまるごと回収: スクロールのループもページ送りもThunderbitのAIが面倒を見て、商品名・価格・画像といった整った行データをCSVやSheetsへ書き出します。
- テスト用の参照データを用意: 期待されるUIのデータをThunderbitで手早くかき集め、そのうえでSeleniumテストにスクロールさせ、UIが一致するか突き合わせます。
- テスト開発のスピードアップ: Thunderbitの「AIでフィールドを提案」がセレクタや構造の見当をつけてくれるので、Seleniumのロケーターも書き起こしやすくなります。
ワークフローの例:
- 動きのあるECページの商品を、Thunderbitですべて拾い上げる(スクロールも抽出も丸ごと任せる)。
- 集めたデータをGoogle SheetsかCSVへ書き出す。
- Seleniumテストにページを送らせ、表示された商品情報を集めてThunderbitのデータセットと照合する。
- 全商品が揃っていること、正しく読み込まれていること、抜けがないことをアサートで確かめる。
この二段構えにすれば、脆いスクレイピングコードと格闘する時間を圧縮でき、本来注力すべき検証へ手を回せます。規模が大きく動きの多いサイトほど、Thunderbitのサブページスクレイピングと定期スクレイピングが効いてきます。
スマートスクレイピングのためにThunderbit Chrome拡張を試す
実践例: 実際のSeleniumテストケースで効率的にスクロールする
理屈はこのくらいにして、実際にコードを動かしてみましょう。以下は、現場のシナリオに合わせて手を加えながら使える雛形です。
1. 大きな表をスクロールする
独自のスクロールバーを抱えたデータグリッドを想定します。
WebElement table = driver.findElement(By.id("data-table"));
js.executeScript("arguments[0].scrollTop = arguments[0].scrollHeight", table);
これで表の一番下まで送られます。行が出てくるたびに検証したいなら、刻みながらループを回しましょう。
2. 無限スクロールのフィードをたどる
prev_count = 0
while True:
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(2)
posts = driver.find_elements(By.CSS_SELECTOR, ".post")
if len(posts) == prev_count:
break
prev_count = len(posts)
追加の投稿が途切れるまで回し続けて、すべての投稿を読み込みます。
3. 遅延読み込み画像を検証する
List<WebElement> images = driver.findElements(By.tagName("img"));
for (WebElement img : images) {
if ("lazy".equals(img.getAttribute("loading"))) {
js.executeScript("arguments[0].scrollIntoView(true);", img);
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
wait.until(d -> (Boolean) ((JavascriptExecutor)d).executeScript("return arguments[0].complete && arguments[0].naturalWidth > 0;", img));
Assert.assertTrue((Integer) js.executeScript("return arguments[0].naturalWidth;", img) > 0);
}
}
遅延読み込みの画像を一枚ずつ画面内へ送り込み、読み込みが済んでいるか見ていきます。
4. カルーセルを横スクロールする
WebElement carousel = driver.findElement(By.className("carousel"));
js.executeScript("arguments[0].scrollBy(300, 0);", carousel);
カルーセルを右方向へ300pxぶん送ります。
5. コンテンツ読み込み失敗を検出する
ひとスクロールごとに、明示的待機で新しい中身やローディング中のスピナーを見張ります。待ち時間を超えたら、その瞬間の状態を記録に残し、失敗として扱いましょう。
ステップバイステップガイド: Seleniumで効率的なスクロールを実装する
データスクレイピングのベストプラクティスを詳しく学ぶ Get Started Free
そのまま手順表として使えるチェックリストを置いておきます。
- そもそもスクロールが要るか見極める: その中身は隠れているのか、遅延読み込みなのか、それともページ送りされているのか?
- 要素の存在を押さえる: 明示的待機を挟んで、要素がDOM上に来ていることを確かめる。
- 手法を選び分ける:
- 正確さを取るなら要素までスクロール。
- 段階的な読み込みならピクセル単位で送る。
- 無限スクロールならループで回す。
- スクロールを組み込む: 状況に応じてJavaScriptかActions APIを当てる。
- 送るたびに足並みを揃える: 固定sleepには頼らず、新しい中身が来るのを待つ。
- 中身を検証する: 送った後、要素が出ていて、読み込まれていて、触れる状態かを確かめる。
- ブラウザ別に詰める: 対象ブラウザを一通り試し、保険としてJSを用意する。
- 抽出にThunderbitを噛ませる: 大きめのデータセットの先取りや検証にThunderbitを使う。
- 無駄な送りを削る: 必要な分だけ動かす。
- 判断を書き残す: なぜその手を選んだのか、コメントで残しておく。
| ステップ | 主なアクション |
|---|---|
| 必要性を確認 | このケースでスクロールは必要か? |
| 要素の存在 | DOMに要素があるか待機する |
| 方法を選ぶ | 要素、ピクセル、ループ、コンテナスクロール |
| 実装 | 必要に応じてJS/Actions/キーを使う |
| 同期 | 各スクロール後にコンテンツを待つ |
| 検証 | 表示と正しさをアサートする |
| ブラウザ最適化 | Chrome、Firefox、Edge、Safariでテストする |
| Thunderbit連携 | データ抽出/検証に使う |
| 最小化 | 無駄なスクロールを避ける |
| 文書化 | 手法をコメントで説明する |
まとめと重要ポイント
堅牢なモダンWebテスト自動化を支える土台——それが、Seleniumで効率よくスクロールできる力です。動的コンテンツと無限スクロールがすっかり標準になった今、UIを本当の意味で検証するには、生身のユーザーと同じ動きをテストにも踏ませるしかありません。ここまでの勘どころを、最後にまとめておきます。
- 狙いを定めて送る: どこで、なぜスクロールが要るのかを見極める。「見えているはず」と祈るだけでは話になりません。
- 道具を選び分ける: 正確さなら要素までスクロール、しなやかさならJavaScript、ネイティブな挙動ならActions API(対応ブラウザに限る)。
- 足並みを揃えて確かめる: 送った後は必ず読み込みを待ち、表示と中身の両方を確認する。
- ブラウザごとに詰める: どの環境でもスクロール処理を試し、どこでも効く保険としてJavaScriptを添える。
- Thunderbitを味方につける: SeleniumにThunderbitを組み合わせれば、スクロールの多いページや動的ページほど、抽出と検証が一気に速まります。
Seleniumテストをもう一段引き上げたいなら、まず手を動かすのが一番の近道です。より賢く、より速いテスト開発に向けて、ThunderbitのChrome拡張機能を一度試してみてください。自動化の引き出しをさらに増やしたい方は、Thunderbit Blogの深掘り記事やチュートリアルものぞいてみるとよいでしょう。
楽しくスクロールしましょう。そして、テストがいつも探しているものを見つけられますように。
よくある質問
1. Seleniumでは、DOM上に存在する要素に操作できないことがあるのはなぜですか?
Seleniumが要素を自動では画面内へ送らないためです。要素が表示範囲の外にあると、ElementNotInteractableExceptionが顔を出すことがあります。触る前に、スクロール操作でその要素を表に出してやりましょう。
2. Seleniumで無限スクロールページを扱う最善の方法は何ですか?
ループで対処します。最下部まで送り、新しい中身が読み込まれるのを待ち、追加が止まるまで繰り返す——この流れです。固定sleepではなく、中身の変化に結びつけた明示的待機を必ず使ってください。
3. スクロールコードをすべてのブラウザで動くようにするにはどうすればいいですか?
いちばん潰しが利くのはJavaScriptのexecute_scriptです。Actions APIはChrome/Edgeでこそ快調ですが、Safariや旧版のFirefoxでは効かないことがあります。対象ブラウザは漏れなく試してください。
4. メインページだけでなく、コンテナや表の中もスクロールできますか?
できます。JavaScriptで、対象のコンテナ要素にscrollTopやscrollByを与えるだけです。たとえば: js.executeScript("arguments[0].scrollTop = arguments[0].scrollHeight", tableElement);
5. ThunderbitはSeleniumのテスト自動化にどう役立ちますか?
ThunderbitのAIスクレイピングは、動的ページや無限スクロールページからデータを残らず抜き出し、Seleniumテスト向けの参照データとして差し出してくれます。おかげでUIの中身を突き合わせやすくなり、込み入った大量データのサイトほどテスト開発が速く進みます。
6. 2026年になってもスクロールコードを手書きする必要はありますか? それともSeleniumはPlaywrightの自動スクロールに追いついたのでしょうか?
要素に触れる前に表示範囲まで自動でスクロールしてくれるのはPlaywrightや近年のCypressであって、Selenium WebDriverは今も同じ挙動を取りませんし、4.x系の間にそれが変わる気配もありません。裏を返せば、Seleniumでは依然としてスクロールを自前で書くことが前提です(Chromium系ならActions API、それ以外はJavascriptExecutor)。これからテストスイートを白紙から立ち上げる場合、チームにSeleniumの資産が積み上がっていないなら、この自動スクロールこそPlaywrightを選ぶ実質的な決め手のひとつになります。一方で、すでにSeleniumのスイートを抱えて運用している——多くのチームがこの立場ですが——その場合は、本ガイドで示したパターンが今も最適解です。
Selenium、Webスクレイピング、自動化のベストプラクティスについてさらに知りたい方は、Thunderbit Blogをご覧ください。
動的ページ向けのAIウェブスクレイパーを試す Get Started Free


