ほとんどのウェブスクレイピングデータは、Amazon、YouTube などの動的ウェブサイトから取得されます。これらのウェブサイトは、ユーザーの入力に基づき、インタラクティブで応答性の高いユーザーエクスペリエンスを提供します。例えば、YouTubeのアカウントにアクセスすると、表示される動画コンテンツは入力内容に合わせたものになります。その結果、ユーザーのインタラクションによってデータが常に変更されるため、動的サイトのウェブスクレイピングがより困難になる可能性があります。
動的なサイトからデータをスクレイピングするには、ユーザーのウェブサイトとの対話をシミュレートし、JavaScriptによって生成された特定のコンテンツに移動して選択し、AJAX(Asynchronous JavaScript and XML)リクエストを処理する高度な技術を使用する必要があります。
このガイドでは、SeleniumというオープンソースのPythonライブラリを使用して、動的ウェブサイトからデータをスクレイピングする方法を説明します。
Seleniumを使用して動的ウェブサイトからデータをスクレイピングする
動的サイトからデータのスクレイピングを開始する前に、使用するPythonパッケージであるSeleniumについて理解する必要があります。
Seleniumとは?
SeleniumはオープンソースのPythonパッケージであり、動的ウェブサイト上でさまざまな操作やタスクを実行可能にする自動テストフレームワークです。これらのタスクには、ダイアログの開閉、YouTubeでの特定のクエリの検索、フォームへの入力などが含まれ、すべてをお好みのウェブブラウザで行うことができます。
SeleniumをPythonで利用すると、Selenium Pythonパッケージを使用して数行のPythonコードを記述するだけで、ウェブブラウザを制御し、動的ウェブサイトからデータを自動的に抽出できます。
Seleniumの仕組みがわかったところで、さっそく始めましょう。
新しいPythonプロジェクトを作成する
最初に、新しいPythonプロジェクトを作成する必要があります。data_scraping_project
というディレクトリを作成します。ここに、収集したデータとソースコードのファイルがすべて格納されます。このディレクトリには2つのサブディレクトリがあります。
scripts
には、動的ウェブサイトからデータを抽出および収集するすべてのPythonスクリプトが含まれます。data
には、動的ウェブサイトから抽出されたすべてのデータが格納されます。
Pythonパッケージをインストールする
data_scraping_project
ディレクトリを作成した後、動的ウェブサイトからデータをスクレイピング、収集、保存できるように、以下のPythonパッケージをインストールする必要があります。
- Webdriver Manager
- pandas
ターミナルで以下のpip
コマンドを実行して、Selenium Pythonパッケージをインストールできます。
Seleniumは、バイナリドライバを使用して、選択したウェブブラウザを制御します。このPythonパッケージは、サポートされているウェブブラウザ(Chrome、Chromium、Brave、Firefox、IE、Edge、Opera)用のバイナリドライバを提供します。
次に、ターミナルで以下のpip
コマンドを実行して、webdriver-manager
をインストールします。
pandasをインストールするには、次のpip
コマンドを実行します。
何をスクレイピングするか
この記事では、Programming with MoshというYouTubeチャンネルとHacker Newsという2つの異なる場所からデータをスクレイピングします。
Programming with Mosh YouTubeチャンネルから、以下の情報をスクレイピングします。
- 動画のタイトル。
- 動画のリンクまたはURL。
- 画像のリンクまたはURL。
- 特定の動画の再生回数。
- 動画の公開時期。
- 特定のYouTube動画URLからのコメント。
Hacker Newsからは以下のデータを収集します。
- 記事のタイトル。
- 記事へのリンク。
何をスクレイピングするかがわかったので、新しいPythonスクリプト(つまり data_scraping_project/scripts/youtube_videos_list.py)を作成しましょう。
Pythonパッケージをインポートする
まず、データのスクレイピング、収集、CSVファイルへの保存に使用するPythonパッケージをインポートする必要があります。
Webdriverをインスタンス化する
Webdriverをインスタンス化するには、Seleniumが使用するブラウザ(この例ではChrome)を選択し、バイナリドライバをインストールする必要があります。
Chromeには、ウェブページのHTMLコードを表示し、スクレイピングしてデータを収集するためのHTML要素を特定する開発者向けツールがあります。HTMLコードを表示するには、Chromeウェブブラウザでウェブページを右クリックし、要素の検査を選択する必要があります。
Chrome用のバイナリドライバをインストールするには、以下のコードを実行します。
Chrome用のバイナリドライバがマシンにインストールされ、自動的にWebdriverがインスタンス化されます。
Seleniumを使ってデータをスクレイピングする
Selenium でデータをスクレイピングするには、簡単なPython変数(つまり、url)でYouTube URLを定義する必要があります。このリンクから、特定のYouTube URLからのコメントを除く、前述のデータをすべて収集します。
Seleniumは、YouTubeリンクをChrome ブラウザに自動的に読み込みます。さらに、ウェブページ(すべてのHTML要素を含む)の完全な読み込みを確保するために、時間枠(つまり10秒)を指定します。これは、JavaScriptによってレンダリングされたデータをスクレイピングするのに役立ちます。
IDとタグを使ってデータをスクレイピングする
Seleniumの利点の1つは、IDやタグなど、ウェブページ上に提示されたさまざまな要素を使ってデータを抽出できることです。
例えば、ID要素(つまり、post-title
)またはタグ(つまり、h1
とp
)を使ってデータをスクレイピングできます。
あるいは、YouTubeのリンクからデータをスクレイピングする場合は、ウェブページに提示されたIDを使用する必要があります。YouTube URLをウェブブラウザで開き、右クリックして検査を選択してIDを特定します。次に、マウスを使ってページを表示し、チャンネルで紹介されているビデオのリストを保持しているIDを特定します。
Webdriverを使用して、特定されたID内のデータをスクレイピングします。ID属性でHTML要素を見つけるには、find_element()
Seleniumメソッドを呼び出し、第1引数としてBy.ID
を、第2引数としてID
を渡します。
各ビデオのビデオタイトルとビデオリンクを収集するためには、video-title-link ID
属性を使用する必要があります。このID属性を持つ複数のHTML要素を収集するため、find_elements()
メソッドを使用する必要があります。
このコードは以下のタスクを実行します。
- コンテンツのID属性内にあるデータを収集します。
- WebElementコンテンツオブジェクトから、
video-title-link
のID属性を持つすべてのHTML要素を収集します。 - タイトルとリンクを追記するための2つのリストを作成します。
get_attribute()
メソッドを使用して動画のタイトルを抽出し、そのtitle
を渡します。- タイトルリストで動画のタイトルを追記します。
get_atribute()
メソッドを使用して動画のリンクを抽出し、引数としてhref
を渡します。- リンクリストで動画のリンクを追記します。
この時点で、すべてのビデオのタイトルとリンクは、titles
とlinks
という2つのPythonリストに含まれます。
次に、YouTube動画リンクをクリックして動画を視聴する前に、ウェブページで利用可能な画像のリンクをスクレイピングする必要があります。この画像リンクをスクレイピングするには、find_elements()
Seleniumメソッドを呼び出し、第1引数にBy.TAG_NAME
を、第2引数にタグの名前を渡して、すべてのHTML要素を見つける必要があります。
このコードは、contentsと呼ばれるWebElementオブジェクトからimg
タグ名を持つすべてのHTML要素を収集します。また、画像リンクを追記するためのリストを作成し、get_attribute()
メソッドでそれを抽出し、引数としてsrc
を渡します。最後に、画像リンクをimg_links
リストに追記します。
また、ID
とタグ名を使用して、各YouTube動画のより多くのデータをスクレイピングできます。YouTube URLのウェブページでは、ページに掲載されている各動画の再生回数と公開時間を確認できるはずです。このデータを抽出するには、ID
がmetadata-line
のHTML要素をすべて収集し、次にspan
タグ名を持つHTML要素からデータを収集する必要があります。
このコードブロックは、 WebElement contents
オブジェクトからID属性が metadata-line
であるすべてのHTML要素を収集し、再生回数と公開時間を含む span
タグのデータを追記するリストを作成します。
また、タグ名がspan
であるすべてのHTML要素をmeta_data_elements
と呼ばれるWebElementオブジェクトから収集し、このspanデータを含むリストを作成します。次に、span HTML要素からテキストデータを抽出し、span_data
listに追記します。最後に、span_data
リストのデータをmeta_data
に追記します。
span HTML要素から抽出されたデータは、次のようになります。
次に、Pythonのリストを2つ作成し、再生回数と公開時間を別々に保存する必要があります。
ここでは、meta_data
からデータを抽出するPythonのリストを2つ作成し、各サブリストの閲覧数をview_list
に、各サブリストの公開時間をpublished_list
に追記します。
この時点で、動画のタイトル、動画ページのURL、画像のURL、閲覧回数、動画の公開時刻をスクレイピングしました。このデータは、pandas Pythonパッケージを使用して、pandas DataFrameに保存できます。以下のコードを使用して、titles
、links
、img_links
、views_list
、published_list
のリストのデータをpandas DataFrameに保存します。
スクレイピングしたデータは、pandas DataFrameでは次のように表示されます。
この保存されたデータは、to_csv()を使用して、pandasからyoutube_data.csv
というCSVファイルにエクスポートされます。
これで、youtube_videos_list.py
を実行して、すべてが正しく動作することを確認できます。
CSSセレクタを使用してデータをスクレイピングする
Seleniumは、ウェブページ上のCSSセレクタを使用して、HTML要素の特定のパターンに基づいてデータを抽出することもできます。CSSセレクタは、ID、タグ名、クラスなどの属性に応じて、特定の要素をターゲットとするために適用されます。
例えば、以下のHTMLページにはいくつかのdiv
要素があり、そのうちの1つに「inline-code」
というクラス名が付けられています。
CSSセレクタを使って、タグ名がdiv
でクラス名が「inline-code」であるウェブページ上のHTML要素を見つけることができます。これと同じアプローチで、YouTube動画のコメントセクションからコメントを抽出できます。
では、CSSセレクタを使って、このYouTube動画に投稿されたコメントを収集してみましょう。
YouTubeのコメントセクションには、以下のタグとクラス名でアクセスできます。
新しいスクリプト(つまりdata_scraping_project/scripts/youtube_video_
comments.py)を作成しましょう。前と同様に必要なパッケージをすべてインポートし、以下のコードを追加してChromeウェブブラウザを自動的に起動して、YouTube動画のURLを参照し、CSSセレクタを使用してコメントをスクレイピングします。
このコードは、Chromeドライバをインスタンス化し、投稿されたコメントをスクレイピングするためのYouTube動画リンクを定義します。次に、ブラウザでウェブページを読み込み、CSSセレクタに一致するHTML要素が利用可能になるまで10秒間待機します。
次に、ytd-comment-thread-renderer.ytd-item-section-renderer
というCSSセレクタを使用してすべてのcomment
HTML要素を収集し、すべてのコメント要素をcomment_blocks
WebElementオブジェクトに保存します。
次に、comment_blocks WebElementオブジェクト内の各コメントからID author-text
を使用して各作成者の名前を抽出し、ID content-text
を使用してコメントテキストを抽出できます。
このコードは、作成者とコメントのIDを指定します。次に、作成者名とコメントテキストを追記するための2つのPythonリストを作成します。指定されたID属性を持つ各HTML要素をWebElementオブジェクトから収集し、そのデータをPythonリストに追加します。
最後に、スクレイピングしたデータをpandas DataFrameに保存し、そのデータをyoutube_comments_data.csv
というCSVファイルにエクスポートします。
最初の10行の作成者とコメントは、pandas DataFrameでは次のようになります。
クラス名を使用してデータをスクレイピングする
CSSセレクタを使ったデータのスクレイピングに加え、特定のクラス名を元にデータを抽出することもできます。Seleniumを使用してクラス名属性でHTML要素を見つけるには、find_element()
メソッドを呼び出し、第1引数としてBy.CLASS_NAME
を渡し、第2引数としてクラス名を見つける必要があります。
このセクションでは、クラス名を使って、Hacker Newsに投稿された記事のタイトルとリンクを収集します。このウェブページでは、(ウェブページのコードからわかるように)各記事のタイトルとリンクを持つHTML要素に、titleline
というクラス名が付いています。
新しいPythonスクリプト(つまりdata_scraping_project/scripts/hacker_news.py)を作成し、必要なパッケージをすべてインポートして、以下のPythonコードを追加し、Hacker Newsページに投稿された各記事のタイトルとリンクをスクレイピングします。
このコードは、ウェブページのURLを定義し、Chromeウェブブラウザを自動的に起動して、Hacker NewsのURLをブラウズします。CLASS NAME
に一致するHTML要素が利用できるようになるまで10秒待ちます。
そして、各記事のタイトルとリンクを追記する2つのPythonリストを作成します。また、WebElementドライバオブジェクトからtitleline
クラス名を持つ各HTML要素を収集し、story_elements
WebElementオブジェクトで表される各記事のタイトルとリンクを抽出します。
最後に、このコードは記事のタイトルをタイトルリストに追加し、タグ名a
を持つHTML要素をstory_element
オブジェクトから収集します。get_attriubute()
メソッドを使用してリンクを抽出し、そのリンクをリンクリストに追記します。
次に、pandasのto_csv()
メソッドを使用してスクレイピングしたデータをエクスポートする必要があります。タイトルとリンクの両方をCSVファイルhacker_news_data.csv
にエクスポートし、そのデータをディレクトリに保存します。
以下に、最初の5行のタイトルとリンクが、pandas DataFrameにどのように表示されるかを示します。
無限スクロールの扱い方
動的ウェブページの中には、ページの下までスクロールすると、追加のコンテンツが読み込まれるものがあります。一番下まで移動しない場合、Seleniumは画面に表示されているデータしかスクレイピングしない可能性があります。
より多くのデータをスクレイピングするには、ページの一番下までスクロールし、新しいコンテンツが読み込まれるまで待ってから、必要なデータを自動的にスクレイピングするよう、Seleniumに指示する必要があります。例えば、以下のPythonスクリプトは、Python書籍の最初の40件の結果をスクロールして、そのリンクを抽出します。
このコードは、使用するPythonパッケージをインポートし、Chromeをインスタンス化して開きます。次にウェブページに移動し、検索結果ごとにリンクを追記するPythonリストを作成します。
return document.body.scrollHeight
スクリプトを実行して現在のページの高さを取得し、収集するリンクの数を設定します。その後、変数book_count
の値がbook_list
の長さより大きい限り下にスクロールし続け、5秒待ってからページを読み込みます。
return document.body.scrollHeight
スクリプトを実行してウェブページの新しい高さを計算し、ページの下部に達したかどうかをチェックします。ページ下部に達した場合はループを終了します。そうでない場合はlast_height
を更新してスクロールダウンを継続します。最後に、WebElementオブジェクトからタグ名a
を持つHTML要素を収集し、リンクを抽出してリンクリストに追記します。リンクを収集した後、Webdriverを閉じます。
注記: ページが無限スクロールする場合、スクリプトをある時点で終了するには、スクレイピングするアイテムの総数を設定する必要があります。さもないと、コードが実行され続けてしまいます。
Bright Dataを使用したウェブスクレイピング
Seleniumのようなオープンソースのスクレイパーでデータをスクレイピングすることは可能ですが、どうしてもサポートが不足がちです。また、プロセスが煩雑で時間がかかることもあります。強力で信頼性の高いウェブスクレイピングソリューションをお探しであれば、Bright Dataを検討されることをお勧めします。
Bright Dataは、ウェブスクレイピングソリューション、プロキシ、収集済みデータセットを含むさまざまなツールやサービスを提供することで、公開されたウェブデータのスクレイピングを可能にするウェブデータプラットフォームです。また、ホストされたWeb Scraper IDEを使用して、JavaScriptコーディング環境で独自のスクレイパーを設計することも可能です。
Web Scraper IDEは Indeedスクレイパー、Walmartスクレイパーのテンプレートなど、さまざまな人気のある動的ウェブサイト向けの構築済みスクレイピング機能とコードテンプレートも搭載しています。つまり、開発のスピードアップや迅速な拡張が容易なのです。
Bright Dataは、JSON、NDJSON、CSV、Microsoft Excelなど、データをフォーマットするための幅広いオプションを提供します。また、さまざまなプラットフォームと統合されているため、スクレイピングしたデータを簡単に配信できます。
まとめ
動的ウェブサイトからデータをスクレイピングするには、労力と計画が必要です。Seleniumを使えば、どんな動的ウェブサイトとも自動的に対話処理を行い、データを収集できます。
Seleniumを使用してデータをスクレイピングすることは可能ですが、時間がかかり、複雑です。そのため、動的ウェブサイトのスクレイピングにはWeb Scraper IDEを使用することをお勧めします。構築済みのスクレイピング機能とコードテンプレートを使用して、すぐにデータの抽出を開始できます。
クレジットカードは必要ありません