webスクレイピングやPythonのお勉強をかねて、Jリーグ選手名鑑の情報をcsvファイルに出力するツールを作ってみました。需要ある?
いちおう本ブログ内でツールで出力した一覧もあるのでそっちを直接活用いただく方が早いかも。
1. 事前準備
Anacondaのインストール
Python3で学ぶデータ分析・AI・機械学習 AI-interのPython3入門
を参考にしてインストールよろしく。
Seleniumuのインストール
Windows PowerShellを起動し conda install -c conda-forge selenium と打てばOK。
BeautifuSoupのインストール
Windows PowerShellを起動し conda install beautifulsoup4 と打てばOK。
Chromeドライバーのインストール
SeleniumuはWebブラウザを自動的に動かしてWebの情報を取得するツールなのでブラウザ対応のドライバーが必要になります。
Google Chrome の使用を前提に以下のサイトからダウンロードします。
ChromeDriver – WebDriver for Chrome
事前に使用中の Google Crome の版数を調べておき 右上の 縦3つの・>ヘルプ(H)>Google Chrome(G) について から 例えば以下の表示の’87’ってのにあったドライバをダウンロードします。 ” バージョン: 87.0.4280.141(Official Build) (64 ビット)”
とりあえず C:\jData フォルダを作り、ダウンロードファイルをZIPで解凍したchromedriver.exeをたそのフォルダに置けば本ブログのプログラムは動くはずです。
2.ソースファイル
2.1 簡易版
(1) 概略
- Jリーグ選手名鑑のトップページ記載の情報が CSVファイルとして収集されます。
- C:\JData フォルダ(1.事前準備 4.Cromeドライバーのインストールで作成)配下に Jleaguers_作成日付.csv ファイルとして格納されます。
- 出力項目は、”クラブ”,”背番号”,”HG”,”名前”,”Pos”,”出生地”,”生年月日”,”身長”,”体重”,”出場試合数”,”ゴール数”,”詳細URL” です。
※1/14 ”身長”と”体重”を分離しました。 - プログラム起動後3,4分で出力されるはずです。
(2) 起動方法
- (3)のコードを”適当.py”というファイル名でC:\JData配下に格納してください。
※私は Jleaguers_collect_light.py って名前にしてます - スタートからWindows PowerShell を起動し python 適当.py を入力し起動します。
※何かエラーでるけど数分あればcsvファイルができるのでまあOKかと
(3) コード
※1/14 ”身長”と”体重”の分離と文字化け対処の修正
from selenium import webdriver
from time import sleep
from bs4 import BeautifulSoup
import csv
import datetime
browser = webdriver.Chrome("C:\jData\chromedriver")
target_url ="https://www.jleague.jp/player/"
browser.get(target_url)
sleep(3)
error_flg = False
try:
browser.execute_script("window.scrollTo(0,document.body.scrollHeight);")
sleep(120)
except Exception:
print("画面スクロール中にエラーが発生しました。")
error_flg = True
soup = BeautifulSoup(browser.page_source, "html.parser")
trs = soup.select("table > tbody > tr")
players =[]
for tr in trs:
club = tr.select("td:nth-child(2)")[0].text
number = tr.select("td:nth-child(3)")[0].text
hg = tr.select("td:nth-child(5)")[0].text
name = tr.select("td:nth-child(6)")[0].text.replace("\u3000"," ")
position = tr.select("td:nth-child(7)")[0].text
hometown = tr.select("td:nth-child(8)")[0].text
birthday = tr.select("td:nth-child(9)")[0].text
# form = tr.select("td:nth-child(10)")[0].text
height = tr.select("td:nth-child(10)")[0].text.split('/')[0]
weight = tr.select("td:nth-child(10)")[0].text.split('/')[1]
participation = tr.select("td:nth-child(11)")[0].text
goal = tr.select("td:nth-child(12)")[0].text
i_url = "https://www.jleague.jp"+tr.get("data-href")
players.append([club,number,hg,name,position,hometown,birthday,height,weight,participation,goal,i_url])
table_head = ["クラブ","背番号","HG","名前","Pos","出生地","生年月日","身長","体重","出場試合数","ゴール数","詳細"]
csv_date= datetime.datetime.today().strftime("%Y%m%d")
csv_file_name= "C:\jData\Jleaguers_"+csv_date+".csv"
f=open(csv_file_name,"w",encoding='utf_8_sig',errors="ignore")
writer = csv.writer(f,lineterminator="\n")
writer.writerow(table_head)
for player in players:
writer.writerow(player)
f.close()
(4) 出力結果
2020年1月10日の出力は以下 Jリーガ:1901名
2.1 詳細版
(1) 概略
- Jリーグ選手名鑑のトップページ記載の情報+そこからリンクされてる個人毎のページから前所属情報(最大10個)と英名が CSVファイルとして収集されます。
- C:\JData フォルダ(1.事前準備 4.Cromeドライバーのインストールで作成)配下に Jleaguers_full_作成日付.csv ファイルとして格納されます。
- 出力項目は、”クラブ”,”背番号”,”HG”,”名前”,“英名”,”Pos”,”出生地”,”生年月日”,”身長”,”体重”,”出場試合数”,”ゴール数”,”J初出場日”,”J初得点日”,”代表出場数”,“所属1”,・・・,”所属10”です。
- 2020年版の1900名だとプログラム起動約70~80分程度で出力されるはずです。
高速化するため”ヘッドレスモード“ってやつで動かしてるのでいちいちGoogle Chromeが起動しません。Windows PowerShellの画面を眺めてると実行結果がスクロールされていって動いてるのがわかりますが、よくみると7行毎に”https://www.jleague.jp/player/1400351/”とか表示されていて、別のブラウザで開いてみるとチーム名が解るので今どのあたりまで進んでいるのかわかります。J1の北から南、J2の北から南、J3の北から南って順番に進みます。
他に要望あればコメントかツイッターかで教えてください。
※1/14 ”身長”と”体重”を分離および”J初出場日”,”J初得点日”,”代表出場数”を追加しました。
(2) 起動方法
- (3)のコードを”適当.py”というファイル名でC:\JData配下に格納してください。
※私は Jleaguers_collect_full.py って名前にしてます - スタートからWindows PowerShell を起動し python 適当.py を入力し起動します。
(3) コード
※1/14 ”身長”と”体重”を分離および”J初出場日”,”J初得点日”,”代表出場数”を追加しました。
from selenium import webdriver
from time import sleep
from bs4 import BeautifulSoup
import csv
import datetime
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument('--headless')
browser = webdriver.Chrome("C:\jData\chromedriver",options=options)
target_url ="https://www.jleague.jp/player/"
browser.get(target_url)
sleep(2)
error_flg = False
try:
browser.execute_script("window.scrollTo(0,document.body.scrollHeight);")
sleep(120)
except Exception:
print("画面スクロール中にエラーが発生しました。")
error_flg = True
soup = BeautifulSoup(browser.page_source, "html.parser")
trs = soup.select("table > tbody > tr")
players =[]
for tr in trs:
club = tr.select("td:nth-child(2)")[0].text
number = tr.select("td:nth-child(3)")[0].text
hg = tr.select("td:nth-child(5)")[0].text
name = tr.select("td:nth-child(6)")[0].text.replace("\u3000"," ")
position = tr.select("td:nth-child(7)")[0].text
hometown = tr.select("td:nth-child(8)")[0].text
birthday = tr.select("td:nth-child(9)")[0].text
# form = tr.select("td:nth-child(10)")[0].text
height = tr.select("td:nth-child(10)")[0].text.split('/')[0]
weight = tr.select("td:nth-child(10)")[0].text.split('/')[1]
participation = tr.select("td:nth-child(11)")[0].text
goal = tr.select("td:nth-child(12)")[0].text
i_url = "https://www.jleague.jp"+tr.get("data-href")
# players.append([club,number,hg,name,position,hometown,birthday,form,participation,goal,i_url])
players.append([club,number,hg,name,position,hometown,birthday,height,weight,participation,goal,i_url])
# print(len(players))
# タイトル行をcsvファイルに書き出し
#table_head = ["クラブ","背番号","HG","名前","英名","Pos","出生地","生年月日","身長/体重","出場試合数","ゴール数"]
table_head = ["クラブ","背番号","HG","名前","英名","Pos","出生地","生年月日","身長","体重","出場試合数","ゴール数"]
table_head_add =["J初出場","J初得点","代表出場数","所属1","所属2","所属3","所属4","所属5","所属6","所属7","所属8","所属9","所属10"]
table_head =table_head + table_head_add
csv_date= datetime.datetime.today().strftime("%Y%m%d")
csv_file_name= "C:\jData\Jleaguers_full_"+csv_date+".csv"
# f=open(csv_file_name,"w",errors="ignore")
f=open(csv_file_name,"w",encoding='utf_8_sig',errors="ignore")
writer = csv.writer(f,lineterminator="\n")
writer.writerow(table_head)
# 所属歴の読みだしおよび選手毎にcsvファイルの書き出し
#debug =0
for player in players:
# browser.get(player[10])
browser.get(player[11])
sleep(0.2)
t_soup = BeautifulSoup(browser.page_source, "html.parser")
if t_soup.find(class_="clubPlayerNameBox"):
english = t_soup.find(class_="clubPlayerNameBox").select("li:nth-child(2)")[0].p.text
affiliations = t_soup.find(class_="clubProfileBox").text.replace("\n","").split("-")
else:
english = ""
affiliations=[]
if len(affiliations)>10:
affiliations = affiliations[:10]
else:
for i in range(10-len(affiliations)):
affiliations.append("")
first_play_date = t_soup.find(class_="playerDateTable").select("tbody > tr:nth-child(4) > td")[0].text
first_goal_date = t_soup.find(class_="playerDateTable").select("tbody > tr:nth-child(5) > td")[0].text
japan=0
if t_soup.find(class_="playerDateTable").select("tbody > tr:nth-child(6) > td"):
japan = t_soup.find(class_="playerDateTable").select("tbody > tr:nth-child(6) > td")[0].text.replace("回","")
# table_body = player[:4]+[english]+ player[4:10]+affiliations
table_body = player[:4]+[english]+ player[4:11]+[first_play_date,first_goal_date,japan]+affiliations
writer.writerow(table_body)
# debug = debug +1
# if debug >50:
# break
f.close()
(4) 出力結果
2020年1月11日の出力は以下 Jリーガ:1901名
3. その他
動作しないとか、要望とかあればお気軽にコメントかツイッターでよろしく。こちらも素人で勉強しながらなので、対応は鬼のように遅いと思いますが、極力対応させていただきします。
ゆくゆくは、Jリーグ等のデータを様々な検索手段で取得、分析できるサイトを作りたいと思ってますが、Python関連の各種フレームワークの環境構築方法が良くわからんです。そいつもぼちぼち勉強していきます。
コメント
[…] Jリーグ選手名鑑収集ツール webスクレイピングやPythonのお勉強をかねて、… […]