0
0

【備忘録】Python×Seleniumでデータ収集を自動化

Posted at

はじめに

Pythonの「requests」と「bs4(beautifulsoup)」を使って、ウェブサイトからデータをスクレイピングしようとしましたが、そのサイトは動的にデータを表示するタイプだったため、思うようにデータを取得することができませんでした。

そこで、「Selenium」を試したところ、うまくスクレイピングができましたので、備忘録として「Python × Selenium」を使ったスクレイピングの方法をまとめておきたいと思います。

想定する読者

  • Python × Seleniumでデータ収集を自動化したい方

Seleniumとは?

Seleniumは、ウェブブラウザを自動で操作するためのオープンソースのテスト自動化ツールです。ウェブアプリケーションの機能テストやスクレイピング、ブラウザ操作の自動化に使用されます。

Seleniumは、開発者やテスターが実際にブラウザを使って行う操作をプログラムでシミュレートすることができます。

主な特徴

  1. ブラウザ自動操作
    • Seleniumを使用すると、ブラウザで行う操作(ページの読み込み、リンクのクリック、テキストの入力、フォームの送信など)を自動化できます
    • テストや定型作業の効率を大幅に向上させることができます
  2. 複数のブラウザやプラットフォームに対応
    • Seleniumは、Google Chrome、Firefox、Microsoft Edge、Safariなど主要なブラウザで動作します
    • Windows、macOS、Linuxといった様々なプラットフォームでも使用可能です
  3. 多言語対応
    • Seleniumは、Python、Java、C#、Ruby、JavaScriptなどのさまざまなプログラミング言語で操作できるため、開発環境に合わせて選択できます
  4. 動的なコンテンツにも対応
    • JavaScriptで動的に生成されるコンテンツや、複雑なWebページの処理を自動化するのに適しています
    • 通常のリクエストベースのスクレイピングでは取得できない動的なデータも扱うことができます

Seleniumの構成要素

  1. Selenium WebDriver
    • WebDriverは、実際にブラウザを自動操作するためのエンジンです。これを通じて、プログラムからブラウザに指示を送り、ユーザーがブラウザ上で行う操作を模倣できます
    • WebDriverは、各ブラウザ用に異なるドライバー(例:ChromeDriver、EdgeDriverなど)を使用して動作します

環境構築

Windows10 or Windows11 64bit
pip 24.2
Python 3.8.10
Selenium 4.17.2

Seleniumのインストール方法
pip install selenium
WebDriverについて

Selenium 4以上では、WebDriverの手動ダウンロードは基本的に不要です

Seleniumが自動的に適切なWebDriverをダウンロード・管理してくれます。
ただし、手動で特定のバージョンのWebDriverを管理したい場合や、プロジェクトの要件に応じては、webdriver_managerライブラリなどを使用します。

基本的な使い方

Seleniumの基本的は書き方を示します。
このプログラムは、PythonのSeleniumライブラリを使用して自動的にブラウザを操作し、Googleのウェブページにアクセスするものです。
Selenium 4以上と未満で挙動は同じです。

Selenium 4以上を使用する場合

selenium_helloworld.py
from selenium import webdriver  # Seleniumのwebdriverモジュールをインポート

# Chromeドライバーを使って新しいブラウザウィンドウを開く
driver = webdriver.Chrome()

# 指定したURL(ここではGoogleのホームページ)を開く
driver.get('https://www.google.com/')

# 現在のタブまたはウィンドウを閉じる
driver.close()

# ブラウザ全体(すべてのウィンドウやタブ)を終了する
driver.quit()

Selenium 4未満を使用する場合

selenium_helloworld.py
from selenium import webdriver  # Seleniumのwebdriverモジュールをインポート
+ from webdriver_manager.chrome import ChromeDriverManager  # webdriver_managerでChromeDriverを管理


# Chromeドライバーを使って新しいブラウザウィンドウを開く
- driver = webdriver.Chrome()
+ # Chromeドライバーを自動でインストール
+ driver = webdriver.Chrome(ChromeDriverManager().install())

# 指定したURL(ここではGoogleのホームページ)を開く
driver.get('https://www.google.com/')

# 現在のタブまたはウィンドウを閉じる
driver.close()

# ブラウザ全体(すべてのウィンドウやタブ)を終了する
driver.quit()
  1. from selenium import webdriver

    • Seleniumのwebdriverモジュールをインポートしています
    • このモジュールを使用することで、ブラウザをプログラムで制御することができます
  2. driver = webdriver.Chrome()

    • SeleniumのChromeドライバーを使用して、新しいChromeブラウザウィンドウを開きます
    • この時点で、プログラムによってChromeが自動的に操作可能な状態になります
  3. driver.get('https://www.google.com/')

    • getメソッドを使って、指定されたURLにアクセスします
    • ここでは、Googleのホームページにアクセスしています
    • ブラウザが指定されたURLを開き、そのページを表示します
  4. driver.close()

    • 現在開いているブラウザのタブまたはウィンドウを閉じます
    • もし複数のタブやウィンドウが開いていた場合でも、現在操作中のものだけを閉じます
  5. driver.quit()

    • ブラウザ全体を終了します
    • このコマンドは、すべてのタブやウィンドウを閉じるとともに、Seleniumのドライバーも終了します
    • Chromeブラウザは完全に閉じられ、プログラムによる操作が終了します

詳しくは公式ドキュメントを参照ください。
https://selenium-python.readthedocs.io/

応用例

Google Choromeでキーワードを指定し、Webページのタイトルを取得するプログラムを示します。
タイトルは指定した個数分取得しますが、ページ遷移を考慮していないため、現状は1ページ目のタイトルしか取得できません。(ここは今後修正します)

get_titles_from_google_chrome.py
from selenium import webdriver
from selenium.webdriver.common.by import By
import time

class GoogleScraperSelenium:
    """
    Google検索を自動化し、検索結果のタイトルを取得するためのクラス。

    Attributes:
        keyword (str): 検索キーワード。
        num_results (int): 取得する検索結果の件数。
        url (str): 検索を実行するURL(Googleの検索ページ)。
        driver (webdriver): SeleniumのWebDriverオブジェクト。
    """

    def __init__(self, keyword, num_results, url):
        """
        コンストラクタ。検索キーワード、取得件数、URLを初期化する。

        Args:
            keyword (str): 検索キーワード。
            num_results (int): 取得する検索結果の件数。
            url (str): 検索ページのURL(GoogleのURLを使用)。
        """
        self.keyword = keyword  # 検索するキーワード
        self.num_results = num_results  # 取得する検索結果の件数
        self.url = url  # 検索するページのURL(Google)
        self.driver = None  # WebDriverオブジェクトの初期化(後でセットアップ)

    def setup_driver(self):
        """
        Chromeドライバーを初期化してセットアップするメソッド。
        Webブラウザを起動し、指定されたURLにアクセスする準備を行う。
        """
        self.driver = webdriver.Chrome()

    def search(self):
        """
        Google検索を実行し、指定された件数の検索結果のタイトルを取得する。

        Returns:
            results (list): 検索結果のタイトルを辞書形式でリストに格納したもの。
        """
        self.setup_driver()
        self.driver.get(self.url)
        
        # 検索ボックスを取得し、キーワードを入力して検索を実行
        search_box = self.driver.find_element(By.NAME, 'q')  # name属性が'q'の要素(Googleの検索ボックス)を取得
        search_box.send_keys(self.keyword)  # 検索ボックスにキーワードを入力
        search_box.submit()  # フォームを送信して検索を実行

        time.sleep(2)  # 検索結果ページが表示されるまで2秒待機

        results = []  # 検索結果を保存するリスト
        
        # 検索結果の要素を取得し、指定された件数分タイトルを抽出
        search_results = self.driver.find_elements(By.CSS_SELECTOR, 'div.g.Ww4FFb.vt6azd.tF2Cxc.asEBEc') 
        for result in search_results[:self.num_results]:
            try:
                title = result.find_element(By.TAG_NAME, 'h3').text
            except:
                title = 'タイトルが見つかりませんでした'
            
            results.append({"title": title})

        self.driver.quit()
        
        return results

    def display_results(self, results):
        """
        取得した検索結果のタイトルを表示する。

        Args:
            results (list): 検索結果のタイトルを格納したリスト。
        """
        # 取得した検索結果を順番に表示
        for i, data in enumerate(results):
            print(f"結果 {i + 1}:") 
            print(f"タイトル: {data['title']}") 
            print("-" * 50) 

def main():
    """
    メイン処理。ユーザーから検索キーワードと取得件数を入力させて検索を実行し、
    結果を表示する。
    """
    # 検索キーワードと取得件数をユーザーから入力させる
    keyword = input("検索キーワードを入力してください: ") 
    num_results = int(input("取得する件数を入力してください: ")) 
    url = "https://www.google.com/"  # 検索するURL(Googleのトップページ)

    # GoogleScraperSelenium クラスをインスタンス化し、検索を実行
    scraper = GoogleScraperSelenium(keyword, num_results, url) 
    results = scraper.search()
    
    scraper.display_results(results) 

# メイン処理の実行
main()
実行
python .\main.py
検索キーワードを入力してください: 北千住 良さ
取得する件数を入力してください: 10
結果
結果 1:
タイトル: 北千住の住みやすさ。家賃相場や治安、メリット・デメリットを紹介
--------------------------------------------------
結果 2:
タイトル: 北千住の住みやすさは?都心へのアクセスやおすすめスポット ...
--------------------------------------------------
結果 3:
タイトル: 穴場な街「北千住」は、アクセスの良さと昔ながらの風情が人気 ...
--------------------------------------------------
結果 4:
タイトル: 北千住駅周辺の住みやすさは?治安や家賃相場についてご ...
--------------------------------------------------
結果 5:
タイトル: 【北千住の住みやすさ】成長著しいエネルギッシュな街はどんな ...
--------------------------------------------------
結果 6:
タイトル: エリア分析|足立区最大のターミナル駅がある「北千住」の魅力 ...
--------------------------------------------------
結果 7:
タイトル: 【最新】北千住の住みやすさ徹底解説!下町商店街と大型 ...
--------------------------------------------------
結果 8:
タイトル: 北千住駅周辺の住みやすさは?治安は悪い?家賃相場・口コミ ...
--------------------------------------------------
結果 9:
タイトル: 北千住駅周辺の住みやすさと交通利便性はどう?住環境も ...
--------------------------------------------------
結果 10:
タイトル: 【北千住駅の住みやすさ】クチコミ・街レビュー(東京都足立区)
--------------------------------------------------

正常にタイトルの取得ができました。

おわりに

この記事では、Ptyhon × Seleniumでデータ収集を自動化する方法を示しました。

Seleniumを使って自動化を行いたい方の助けになれば幸いです。

変更履歴

2024/09/17 新規作成

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0