LoginSignup
6
7

More than 3 years have passed since last update.

Python + Seleniumでframe内のテーブルを取得してエクセルに保存

Last updated at Posted at 2019-07-14

はじめに

タイトル通り。
作業自動化のためスクレイピングの勉強中。

確認した環境

Pythonコード

'''
特定のサイトURLから、特定のテーブルデータを取得し
指定のエクセルファイルに保存する
'''
import os
# Excel用ライブラリ読込
import openpyxl
# ブラウザ用ライブラリ読込
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.event_firing_webdriver import EventFiringWebDriver
from selenium.webdriver.support.abstract_event_listener import AbstractEventListener

# Parameters
# webdriver path
webdriver_path = r'/path/to/chromedriver.exe'
# saving excel file path
excel_file_path = r'output.xlsx'
# web site path, info
# sample
access_site = r'https://seleniumhq.github.io/selenium/docs/api/java/index.html'
frame_name = 'classFrame'
table_class_name = 'overviewSummary'

class MyListener(AbstractEventListener):
    def before_navigate_to(self, url, driver):
        # URL遷移直前の処理
        print("before_navigate_to:" + driver.current_url)

    def after_navigate_to(self, url, driver):
        # URL遷移直後の処理
        print("after_navigate_to:" + driver.current_url)

# Excel Workbookオブジェクトを取得
if not os.path.exists(excel_file_path):
    v_wb = openpyxl.Workbook()
else:
    v_wb = openpyxl.load_workbook(excel_file_path)

# アクティブなシートを変数へ
v_ws = v_wb.active

# Chrome用ドライバー読込
options = Options()
# ヘッドレスで動作させる場合、以下をコメントアウト
# options.add_argument('--headless')
driver = webdriver.Chrome(executable_path=webdriver_path, options=options)
v_browser = EventFiringWebDriver(driver, MyListener())

try:
    v_browser.get(access_site)
    frames = v_browser.find_elements(By.TAG_NAME, 'frame')
    if frames:
        print('count of frames = ' + str(len(frames)))
    # frame_nameが定義されている場合、スイッチする
    if frame_name:
        target_frame = v_browser.find_element_by_name(frame_name)
        v_browser.switch_to.frame(target_frame)
    # Tableのclassを指定して取得(複数のTableが見つかる可能性がある場合はelementsにする)
    v_table = v_browser.find_element_by_class_name(table_class_name)
    trs = v_table.find_elements(By.TAG_NAME, 'tr')
    # Tableのheaderを取得
    list_header_line = []
    try:
        # v_table_thread = v_table.find_element(By.TAG_NAME, 'thead')
        ths = v_table.find_elements(By.TAG_NAME, 'th')
    except NoSuchElementException as nsExcep:
        print('NoSuchElementException occured')
        print(nsExcep)
        pass
    else:
        # ヘッダの値を取得
        for i in range(0, len(ths)):
            list_header_line.append(ths[i].text)

    # Tableのbodyを取得
    list_table = []
    for i in range(1, len(trs)):
        tds = trs[i].find_elements(By.TAG_NAME, 'td')
        line = ""
        list_line = []
        for j in range(0, len(tds)):
            list_line.append(tds[j].text)
        list_table.append(list_line)

    for list_line in list_table:
        print(list_line)

    # ヘッダを書き込み
    alphabet_count = 0
    for val in list_header_line:
        v_ws.cell(column=alphabet_count+1, row=1).value = val
        alphabet_count += 1
    # 2行目から、最大行+1まで繰り返す
    line_count = 2
    for list_line in list_table:
        alphabet_count = 0
        for val in list_line:
            v_ws.cell(column=alphabet_count+1, row=line_count).value = val
            alphabet_count += 1
        line_count += 1
finally:
    # ブラウザを閉じる
    driver.quit()

# Excelファイルを保存
v_wb.save(excel_file_path)

メモ

chromeは文字コードの指定方法が見つけられなかったため、文字化け対策できないように思えた。
文字化け対策には以下のようなBeautifulSoupの方法と組み合わせて取得したほうが良いかもしれない。
https://qiita.com/hujuu/items/b0339404b8b0460087f9

参考にしたサイト

https://qiita.com/memakura/items/20a02161fa7e18d8a693
https://www.seleniumqref.com/api/webdriver_gyaku.html
https://www.ex-it-blog.com/Python-Excel-fare
https://qiita.com/Azunyan1111/items/b161b998790b1db2ff7a

6
7
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
6
7