selenium

[Python] seleniumでテーブルの要素をスクレイピングする方法

Seleniumを使用してWebページ上のテーブル要素をスクレイピングするには、まずテーブルのHTML構造を確認し、適切なXPathやCSSセレクタを使用して要素を取得します。

例えば、find_elementfind_elementsメソッドを使ってテーブル全体や行、セルを取得し、各セルのテキストを抽出します。

テーブルの行は<tr>タグ、セルは<td>タグで構成されているため、これらをループで処理してデータを収集します。

テーブル要素の基本構造

HTMLにおけるテーブルの構造

HTMLでは、テーブルはデータを行と列で整理して表示するための要素です。

テーブルは、以下の基本的な構造を持っています。

  • <table>: テーブル全体を囲むタグ
  • <tr>: テーブルの行を定義するタグ
  • <td>: テーブルのセル(データ)を定義するタグ
  • <th>: テーブルのヘッダーセルを定義するタグ(通常は太字で表示される)

この構造により、データを視覚的に整理し、理解しやすく表示することができます。

<table>, <tr>, <td>タグの役割

タグ名役割
<table>テーブル全体を定義する<table>...</table>
<tr>テーブルの行を定義する<tr><td>データ1</td></tr>
<td>テーブルのデータセルを定義する<td>データ1</td>
<th>テーブルのヘッダーセルを定義する<th>ヘッダー1</th>

このように、各タグはテーブルの構成要素として重要な役割を果たしています。

テーブルの属性とクラスの確認方法

テーブルには、さまざまな属性やクラスを設定することができます。

これにより、スタイルや動作をカスタマイズすることが可能です。

主な属性には以下のようなものがあります。

  • border: テーブルの境界線の幅を指定
  • cellpadding: セル内の余白を指定
  • cellspacing: セル間のスペースを指定
  • class: CSSスタイルを適用するためのクラス名を指定

これらの属性は、HTMLコード内で直接指定することができます。

例えば、以下のように記述します。

<table border="1" cellpadding="5" class="my-table">
    <tr>
        <th>ヘッダー1</th>
        <th>ヘッダー2</th>
    </tr>
    <tr>
        <td>データ1</td>
        <td>データ2</td>
    </tr>
</table>

このように、テーブルの属性やクラスを設定することで、見た目やレイアウトを調整することができます。

Seleniumを使ったテーブル要素の取得方法

テーブル全体を取得する方法

Seleniumを使用して、テーブル全体を取得するには、find_elementメソッドを使います。

以下のサンプルコードでは、テーブル全体を取得し、その内容を表示します。

from selenium import webdriver
# WebDriverの初期化
driver = webdriver.Chrome()
# 対象のURLを開く
driver.get('https://example.com')
# テーブル全体を取得
table = driver.find_element('xpath', '//table')
# テーブルのHTMLを表示
print(table.get_attribute('outerHTML'))
# WebDriverを終了
driver.quit()
<table>...</table>

このコードでは、指定したURLのページからテーブル全体を取得し、そのHTMLを表示しています。

行(<tr>)を取得する方法

テーブルの行を取得するには、find_elementsメソッドを使用します。

以下のサンプルコードでは、テーブル内のすべての行を取得し、それぞれの行のテキストを表示します。

from selenium import webdriver
# WebDriverの初期化
driver = webdriver.Chrome()
# 対象のURLを開く
driver.get('https://example.com')
# テーブルの行を取得
rows = driver.find_elements('xpath', '//table/tr')
# 各行のテキストを表示
for row in rows:
    print(row.text)
# WebDriverを終了
driver.quit()
データ1
データ2
データ3

このコードでは、テーブル内のすべての行を取得し、それぞれの行のテキストを表示しています。

セル(<td>)を取得する方法

テーブルのセルを取得するには、行を取得した後に、各行内のセルを取得します。

以下のサンプルコードでは、各行のセルを取得し、そのテキストを表示します。

from selenium import webdriver
# WebDriverの初期化
driver = webdriver.Chrome()
# 対象のURLを開く
driver.get('https://example.com')
# テーブルの行を取得
rows = driver.find_elements('xpath', '//table/tr')
# 各行のセルを表示
for row in rows:
    cells = row.find_elements('xpath', './td')
    for cell in cells:
        print(cell.text)
# WebDriverを終了
driver.quit()
データ1
データ2
データ3

このコードでは、各行のセルを取得し、それぞれのセルのテキストを表示しています。

find_elementとfind_elementsの違い

  • find_element: 指定した条件に一致する最初の要素を取得します。

要素が見つからない場合は、NoSuchElementExceptionが発生します。

  • find_elements: 指定した条件に一致するすべての要素をリストとして取得します。

要素が見つからない場合は、空のリストが返されます。

この違いを理解することで、必要な要素を適切に取得することができます。

XPathやCSSセレクタを使った要素の指定方法

Seleniumでは、XPathやCSSセレクタを使用して要素を指定することができます。

以下にそれぞれの例を示します。

  • XPathの例:
  table = driver.find_element('xpath', '//table[@class="my-table"]')
  • CSSセレクタの例:
  table = driver.find_element('css selector', 'table.my-table')

XPathは、XML文書の構造を基に要素を指定する方法で、非常に柔軟です。

一方、CSSセレクタは、CSSのスタイルルールを基に要素を指定する方法で、簡潔に記述できます。

どちらを使用するかは、状況に応じて選択します。

テーブルデータのスクレイピング手順

テーブルの行をループで処理する方法

テーブルの行をループで処理することで、各行のデータを取得することができます。

以下のサンプルコードでは、テーブルの行をループ処理し、各行の情報を表示します。

from selenium import webdriver
# WebDriverの初期化
driver = webdriver.Chrome()
# 対象のURLを開く
driver.get('https://example.com')
# テーブルの行を取得
rows = driver.find_elements('xpath', '//table/tr')
# 各行をループ処理
for row in rows:
    print(row.text)
# WebDriverを終了
driver.quit()
データ1
データ2
データ3

このコードでは、テーブルの各行をループ処理し、行のテキストを表示しています。

各セルのテキストを抽出する方法

各行のセルからテキストを抽出するには、行を取得した後に、各行内のセルを取得します。

以下のサンプルコードでは、各行のセルのテキストを抽出して表示します。

from selenium import webdriver
# WebDriverの初期化
driver = webdriver.Chrome()
# 対象のURLを開く
driver.get('https://example.com')
# テーブルの行を取得
rows = driver.find_elements('xpath', '//table/tr')
# 各行のセルのテキストを抽出
for row in rows:
    cells = row.find_elements('xpath', './td')
    for cell in cells:
        print(cell.text)
# WebDriverを終了
driver.quit()
データ1
データ2
データ3

このコードでは、各行のセルを取得し、それぞれのセルのテキストを表示しています。

取得したデータをリストや辞書に格納する方法

取得したデータをリストや辞書に格納することで、後でデータを扱いやすくなります。

以下のサンプルコードでは、テーブルのデータをリストに格納します。

from selenium import webdriver
# WebDriverの初期化
driver = webdriver.Chrome()
# 対象のURLを開く
driver.get('https://example.com')
# テーブルの行を取得
rows = driver.find_elements('xpath', '//table/tr')
# データを格納するリスト
data = []
# 各行のセルのテキストを抽出してリストに格納
for row in rows:
    cells = row.find_elements('xpath', './td')
    row_data = [cell.text for cell in cells]
    data.append(row_data)
# 取得したデータを表示
print(data)
# WebDriverを終了
driver.quit()
[['データ1', 'データ2'], ['データ3', 'データ4']]

このコードでは、各行のセルのテキストをリストに格納し、最終的に全データを表示しています。

例外処理とエラーハンドリング

スクレイピングを行う際には、例外処理を行うことで、エラーが発生した場合でもプログラムが正常に動作し続けるようにすることが重要です。

以下のサンプルコードでは、例外処理を追加しています。

from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
# WebDriverの初期化
driver = webdriver.Chrome()
try:
    # 対象のURLを開く
    driver.get('https://example.com')
    # テーブルの行を取得
    rows = driver.find_elements('xpath', '//table/tr')
    # データを格納するリスト
    data = []
    # 各行のセルのテキストを抽出してリストに格納
    for row in rows:
        try:
            cells = row.find_elements('xpath', './td')
            row_data = [cell.text for cell in cells]
            data.append(row_data)
        except NoSuchElementException:
            print("セルが見つかりませんでした。")
    # 取得したデータを表示
    print(data)
except Exception as e:
    print(f"エラーが発生しました: {e}")
finally:
    # WebDriverを終了
    driver.quit()

このコードでは、tryブロック内でエラーが発生した場合に、exceptブロックでエラーメッセージを表示し、finallyブロックでWebDriverを終了します。

これにより、エラーが発生してもプログラムが適切に終了します。

動的なテーブルのスクレイピング

JavaScriptで生成されるテーブルの扱い方

動的なウェブページでは、JavaScriptによってテーブルが生成されることがあります。

この場合、ページが完全に読み込まれる前にテーブルを取得しようとすると、要素が見つからないことがあります。

JavaScriptで生成されたテーブルを扱うためには、ページが完全に読み込まれるのを待つ必要があります。

以下のサンプルコードでは、JavaScriptで生成されたテーブルを取得する方法を示します。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# WebDriverの初期化
driver = webdriver.Chrome()
# 対象のURLを開く
driver.get('https://example.com')
# テーブルが表示されるまで待機
WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.XPATH, '//table'))
)
# テーブルを取得
table = driver.find_element('xpath', '//table')
print(table.get_attribute('outerHTML'))
# WebDriverを終了
driver.quit()

このコードでは、WebDriverWaitを使用して、テーブルがページに表示されるまで待機しています。

WebDriverWaitを使った要素の待機

WebDriverWaitは、指定した条件が満たされるまで待機するための便利な機能です。

これにより、動的に生成される要素を確実に取得することができます。

以下のサンプルコードでは、特定の要素が表示されるまで待機する方法を示します。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# WebDriverの初期化
driver = webdriver.Chrome()
# 対象のURLを開く
driver.get('https://example.com')
# 特定の要素が表示されるまで待機
try:
    element = WebDriverWait(driver, 10).until(
        EC.visibility_of_element_located((By.XPATH, '//table/tr'))
    )
    print("テーブルの行が表示されました。")
except Exception as e:
    print(f"エラーが発生しました: {e}")
# WebDriverを終了
driver.quit()

このコードでは、指定したXPathの要素が表示されるまで最大10秒間待機します。

要素が見つかれば、メッセージを表示します。

execute_scriptでJavaScriptを実行する方法

Seleniumでは、execute_scriptメソッドを使用して、JavaScriptを直接実行することができます。

これにより、ページの動作を制御したり、特定のデータを取得したりすることが可能です。

以下のサンプルコードでは、JavaScriptを実行してページの要素を操作する方法を示します。

from selenium import webdriver
# WebDriverの初期化
driver = webdriver.Chrome()
# 対象のURLを開く
driver.get('https://example.com')
# JavaScriptを実行して、特定の要素を取得
table_html = driver.execute_script("return document.querySelector('table').outerHTML;")
print(table_html)
# WebDriverを終了
driver.quit()

このコードでは、execute_scriptを使用して、ページ内のテーブルのHTMLを取得しています。

JavaScriptを使うことで、より柔軟にページの要素を操作することができます。

応用例:複雑なテーブルのスクレイピング

ページネーションがあるテーブルのスクレイピング

ページネーションがあるテーブルをスクレイピングする場合、各ページを順番に取得する必要があります。

以下のサンプルコードでは、ページネーションを考慮して、すべてのページのテーブルデータを取得します。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# WebDriverの初期化
driver = webdriver.Chrome()
# 対象のURLを開く
driver.get('https://example.com')
# データを格納するリスト
all_data = []
while True:
    # テーブルの行を取得
    rows = driver.find_elements('xpath', '//table/tr')
    
    # 各行のセルのテキストを抽出してリストに格納
    for row in rows:
        cells = row.find_elements('xpath', './td')
        row_data = [cell.text for cell in cells]
        all_data.append(row_data)
    # 次のページが存在するか確認
    try:
        next_button = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.XPATH, '//a[@class="next"]'))
        )
        next_button.click()  # 次のページへ移動
    except Exception:
        break  # 次のページがない場合はループを終了
# 取得したデータを表示
print(all_data)
# WebDriverを終了
driver.quit()

このコードでは、ページネーションを考慮して、すべてのページのテーブルデータを取得し、リストに格納しています。

テーブル内のリンクやボタンの操作

テーブル内にリンクやボタンが含まれている場合、それらを操作することも可能です。

以下のサンプルコードでは、テーブル内のリンクをクリックして、詳細情報を取得します。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# WebDriverの初期化
driver = webdriver.Chrome()
# 対象のURLを開く
driver.get('https://example.com')
# テーブルの行を取得
rows = driver.find_elements('xpath', '//table/tr')
# 各行のリンクをクリックして詳細情報を取得
for row in rows:
    try:
        link = row.find_element('xpath', './td/a')
        link.click()  # リンクをクリック
        
        # 詳細情報を取得
        detail_info = driver.find_element('xpath', '//div[@class="detail"]').text
        print(detail_info)
        
        driver.back()  # 元のページに戻る
    except Exception as e:
        print(f"エラーが発生しました: {e}")
# WebDriverを終了
driver.quit()

このコードでは、テーブル内のリンクをクリックして詳細情報を取得し、元のページに戻る処理を行っています。

テーブルのフィルタリング機能を利用したスクレイピング

テーブルにフィルタリング機能がある場合、特定の条件でデータを絞り込むことができます。

以下のサンプルコードでは、フィルタリング機能を使用して特定のデータを取得します。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# WebDriverの初期化
driver = webdriver.Chrome()
# 対象のURLを開く
driver.get('https://example.com')
# フィルタリング条件を入力
filter_input = driver.find_element('xpath', '//input[@id="filter"]')
filter_input.send_keys('特定の条件')
# フィルターボタンをクリック
filter_button = driver.find_element('xpath', '//button[@id="filter-button"]')
filter_button.click()
# フィルタリング後のテーブルの行を取得
rows = driver.find_elements('xpath', '//table/tr')
# 各行のセルのテキストを抽出して表示
for row in rows:
    cells = row.find_elements('xpath', './td')
    row_data = [cell.text for cell in cells]
    print(row_data)
# WebDriverを終了
driver.quit()

このコードでは、フィルタリング条件を入力し、フィルターボタンをクリックして、条件に合ったデータを取得しています。

複数ページにまたがるテーブルのデータ収集

複数ページにまたがるテーブルのデータを収集する場合、ページネーションとフィルタリングを組み合わせて使用することができます。

以下のサンプルコードでは、フィルタリングを行った後、すべてのページのデータを収集します。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# WebDriverの初期化
driver = webdriver.Chrome()
# 対象のURLを開く
driver.get('https://example.com')
# フィルタリング条件を入力
filter_input = driver.find_element('xpath', '//input[@id="filter"]')
filter_input.send_keys('特定の条件')
# フィルターボタンをクリック
filter_button = driver.find_element('xpath', '//button[@id="filter-button"]')
filter_button.click()
# データを格納するリスト
all_data = []
while True:
    # テーブルの行を取得
    rows = driver.find_elements('xpath', '//table/tr')
    
    # 各行のセルのテキストを抽出してリストに格納
    for row in rows:
        cells = row.find_elements('xpath', './td')
        row_data = [cell.text for cell in cells]
        all_data.append(row_data)
    # 次のページが存在するか確認
    try:
        next_button = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.XPATH, '//a[@class="next"]'))
        )
        next_button.click()  # 次のページへ移動
    except Exception:
        break  # 次のページがない場合はループを終了
# 取得したデータを表示
print(all_data)
# WebDriverを終了
driver.quit()

このコードでは、フィルタリングを行った後、すべてのページのデータを収集し、リストに格納しています。

これにより、特定の条件に合ったデータを効率的に取得することができます。

まとめ

この記事では、Seleniumを使用してテーブル要素をスクレイピングする方法について詳しく解説しました。

特に、動的なテーブルやページネーション、フィルタリング機能を持つテーブルの扱い方に焦点を当て、実際のコード例を通じて具体的な手法を紹介しました。

これらの知識を活用することで、さまざまなウェブサイトから必要なデータを効率的に収集することが可能になります。

今後は、実際に自分のプロジェクトでこれらのテクニックを試してみて、データ収集のスキルをさらに向上させてください。

関連記事

Back to top button
目次へ