1
1

More than 1 year has passed since last update.

武庫川一文字の青物をデータ分析する 【スクレイピング編】

Posted at

この記事について

関西ショアジギングの聖地、武庫川一文字(通称武庫一)における2007年から2022年現在までの釣果をスクレイピングから可視化分析まで行った。結果だけ見たい方はこちら。

環境

WSL2 Ubuntu18.04
vsCode

モジュールインポート

import itertools
import pandas as pd
import chromedriver_binary
from selenium import webdriver

定数

釣果表と日付選択後表示するボタンは事前にブラウザ上でXpathを確認。

TABLE = "/html/body/center/table/tbody/tr[12]/td"
DISPLAY = "/html/body/center/table/tbody/tr[12]/td/table[2]/tbody/tr[1]/td[2]/button"
ZEN = "/()0123456789"
HAN = "/()0123456789"

スクレイピング

ポイントは以下の3点。
1. ページ間移動
月日を選択することで釣果のテーブルが表示されるため、月日の選択と表示ボタンの押下をselenium経由で実行する必要がある。

years = web_driver.find_element(By.NAME, "year")
year_select = Select(years)
year_select.select_by_value(str(year))
months = web_driver.find_element(By.NAME, "month")
month_select = Select(months)
month_select.select_by_value(str(month).zfill(2))
display_button = web_driver.find_element(By.XPATH, DISPLAY)
display_button.click()

2. 釣果なしでもページはある
2007年9月まではページ自体は存在する(選択できる)が釣果はない。また、釣果があった日のみ掲載があるため、read_htmlとして読み込んだ後、日付行を検索して取得する必要がある。

if len(dfs) != 0: #釣果のない年月は取得しない

3. 異なるテーブル行
日付、釣果状況コメント欄が混在するため、釣果テーブル自体の列数が行ごとに異なる。

if (len(df.columns) == 10) and (len(df) > 1): # 釣果行のみ取得、かつ釣果があるか

以上を踏まえて

import itertools
import pandas as pd
from selenium import webdriver
import chromedriver_binary
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select

URL = "釣果HPのアドレス"
TABLE = "/html/body/center/table/tbody/tr[12]/td"
DISPLAY = "/html/body/center/table/tbody/tr[12]/td/table[2]/tbody/tr[1]/td[2]/button"

ZEN = "/()0123456789"
HAN = "/()0123456789"

def to_hankaku(s):
    return s.translate(str.maketrans(ZEN, HAN))

def trim_dow(s):
    return s.split("(")[0]

web_driver = webdriver.Chrome()
web_driver.get(URL)
monthly_dfs = []

for year, month in itertools.product(
        list(range(2007, 2023)), list(range(1, 13))):
    daily_dfs = []
    print(year, "/", month)

    years = web_driver.find_element(By.NAME, "year")
    year_select = Select(years)
    year_select.select_by_value(str(year))
    months = web_driver.find_element(By.NAME, "month")
    month_select = Select(months)
    month_select.select_by_value(str(month).zfill(2))
    display_button = web_driver.find_element(By.XPATH, DISPLAY)
    display_button.click()

    elem_table = web_driver.find_element(By.XPATH, TABLE)
    html = elem_table.get_attribute('innerHTML')

    dfs = pd.read_html(html, header=0)
    if len(dfs) != 0:  # 釣果のない年月は取得しない
        for i, df in enumerate(dfs):
            if (len(df.columns) == 10) and (len(df) > 1):  # 釣果行のみ取得、かつ釣果があるか
                date_str = df[df["Unnamed: 0"] == "日付"].iat[0, 1]
                df["Year"] = year
                df["Month"] = month
                df["Day"] = int(trim_dow(to_hankaku(date_str)).split("/")[-1])
                if len(df) != 0:
                    daily_dfs.append(df)
        if daily_dfs:
            monthly_dfs.append(pd.concat(daily_dfs))
    else:
        web_driver.back()
web_driver.close()
df = pd.concat(monthly_dfs)
df.to_csv("chouka.csv", index=False)

続きは
データクレンジング編
データ分析編

1
1
1

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