はじめに
タイトル通り。
作業自動化のためスクレイピングの勉強中。
確認した環境
- windows10
- python3
- selenium (chromedriver)
- openpyxl
- サンプルページとしてseleniumのAPI docs
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