データの抽出
いつものBeautifulSoupで。ほとんどpowered by ChatGPTであるが、一部文字化け部分についてはChatGPTは解決できなかったので、加筆している。
必要ライブラリのimport
こちらで必要ライブラリをimportしておく。
import pandas as pd
import numpy as np
import csv
import requests
from urllib.request import urlopen
from bs4 import BeautifulSoup
htmlのパーシング
まとまった情報であれば何でもいいので、J-Leagueの試合結果を例にする。試合結果はこちらのurlから取得できる。
このアドレスのcompetitionの部分をいじれば各年ごとの試合結果を取得できそう。例えば、2000年の日本で行われた全試合結果を取得してみる。ここで、後で詳しくみるが、まず最初にencodingを指定しておくことが重要。
# Parsing HTML with BeautifulSoup
response = requests.get("https://data.j-league.or.jp/SFMS01/search?competition_years=2000")
response.encoding = "utf-8"
bs = BeautifulSoup(response.text, "html.parser")
ヘッダーの取得
後でデータが何か忘れないように、ヘッダーも取得しておく。
# Get table header
headers = []
for th in bs.find("thead").find_all("th"):
headers.append(th.text.strip())
データの取得
これも簡単
# Get data from table
data = []
for tr in bs.find("tbody").find_all("tr"):
row = []
for td in tr.find_all("td"):
row.append(td.text.strip())
data.append(row)
CSVファイルへの書き出し
ここが一番大変だった。何が大変かというと、encodingを”shift-jis”にすると、出てくるCSVファイルがどうしても文字化けしてしまう。そこで、下記のように一度”utf-8″でencodingしつつ、それ以外の文字コードを無視、さらに”utf-8″で再度decodingというややわかりにくい手法を行なっている。
# Write to CSV file
with open("/Users/YourDirectory/Documents/j-league.csv", "w", encoding="utf-8", newline="") as f:
writer = csv.writer(f)
# Convert headers to utf-8 encoding
headers_encoded = [h.encode('utf-8', 'ignore').decode('utf-8') for h in headers]
writer.writerow(headers_encoded)
# Convert data to utf-8 encoding
data_encoded = [[d.encode('utf-8', 'ignore').decode('utf-8') for d in row] for row in data]
writer.writerows(data_encoded)
無事にCSVファイルが完成・・・?
ところがこれでも出てきたCSVファイルを見ると、しっかり文字化けしている。
文字化けの解決方法
これを解決するには、まずcsvファイルをMacのテキストエディットで開く。
これをメニューの「ファイル」→「複製」して、複製したものの名前を.csvにしてから、「標準テキストのエンコーディング」で「日本語(Shift JIS X0213)」を指定すればOK。
forループで1993年から2023年まで一気に
複数年度に渡って情報を抽出する場合、以下のようにすればいい。ほとんどcodeは一緒なので、一気に掲載。
for year in range(1993, 2023):
# Parsing HTML with BeautifulSoup
response = requests.get("https://data.j-league.or.jp/SFMS01/search?competition_years={0}".format(year))
response.encoding = "utf-8"
bs = BeautifulSoup(response.text, "html.parser")
# Get table header
headers = []
for th in bs.find("thead").find_all("th"):
headers.append(th.text.strip())
# Get data from table
data = []
for tr in bs.find("tbody").find_all("tr"):
row = []
for td in tr.find_all("td"):
row.append(td.text.strip())
data.append(row)
# Write to CSV file
with open("/Users/YourDirectory/Documents/j-league{0}.csv".format(year), "w", encoding="utf-8", newline="") as f:
writer = csv.writer(f)
# Convert headers to utf-8 encoding
headers_encoded = [h.encode('utf-8', 'ignore').decode('utf-8') for h in headers]
writer.writerow(headers_encoded)
# Convert data to utf-8 encoding
data_encoded = [[d.encode('utf-8', 'ignore').decode('utf-8') for d in row] for row in data]
writer.writerows(data_encoded)
このcodeを実行すると、j-league1994.csvからj-league2023.csvまで複数のCSVファイルが一気に出てくる。後はこれを以下のコードで結合すれば良い。
#merge all CSV
import glob
csv_files = glob.glob("*.csv")
list = []
for file in csv_files:
list.append(pd.read_csv(file))
df = pd.concat(list)
df.to_csv("merged.csv", index = False)
出てくるCSVファイルもやはり文字化けしているが、上記の要領でテキストエディットを用いて再度変換すればOK。
pandasでの読み込み
といろいろやってみても、実はpandasで読み込むときは変な変換をしないで、そのままのCSVファイルの方でないと、逆に文字化けしてしまっていることもある。ここらへんは、個々の環境と状況に応じて使い分けを。
コメント