3,202 views
この記事は最終更新から 1880日 が経過しています。
前回の (86) NPBプロ野球選手の年別成績を取得する。 では、一人の選手の紹介ページのURLを入力し、一人の選手の年別成績を出力するだけの機能だった。数百人ものプロ野球選手についてこれを手作業で繰り返すのは大変だ。
今回は、NPB様サイトのチームメンバー一覧ページのURLを入力し、そこから個々の選手紹介ページのURLを抽出し、個々の選手の年別成績を出力するように改良する。すなわち、チームを指定すれば所属メンバー全員分のデータが自動で出力されるようにする。
1. 仕様
・NPB様ホームページの1チームの選手一覧ページのURLを入力する。
・そのページから選手個々の紹介ページのURLを自動抽出する。
・選手個々の紹介ページから年別成績を自動抽出する。
・打者成績、投手成績に分けてCSVファイルを自動出力する。
2. プログラム
ちょっと力ずくなところもあるが後で改良しよう…
コマンドライン入力
以下の操作でホークスの全選手の年度別投手成績、年度別打者成績がファイル出力される。
$ mkdir ./da $ mkdir ./pt $ python3 >>> import lib_npb >>> lib_npb.generate_record_file_for_1team("http://npb.jp/bis/teams/rst_h.html", "H")
他のチームのURLは以下の通り。
セ
http://npb.jp/bis/teams/rst_c.html 広島
http://npb.jp/bis/teams/rst_g.html 巨人
http://npb.jp/bis/teams/rst_db.html 横浜
http://npb.jp/bis/teams/rst_t.html 阪神
http://npb.jp/bis/teams/rst_s.html ヤクルト
http://npb.jp/bis/teams/rst_d.html 中日
パ
http://npb.jp/bis/teams/rst_h.html ソフトバンク
http://npb.jp/bis/teams/rst_f.html 日ハム
http://npb.jp/bis/teams/rst_m.html ロッテ
http://npb.jp/bis/teams/rst_l.html 西武
http://npb.jp/bis/teams/rst_e.html 楽天
http://npb.jp/bis/teams/rst_bs.html オリックス
lib_npb.py
import urllib.request from bs4 import BeautifulSoup import csv #//////////////////////////////////////////////////////////////// class NpbPlayer: #------------------------------------------------------------ def __init__(self, name, url): self.name = name self.url = "http://npb.jp" + url self.ary_record_pitch = [] # 投手記録 self.ary_record_bat = [] # 打者記録 #------------------------------------------------------------ # 1選手の投手記録をCSVファイルに出力 def output_record_to_csv_file_pitch(self, fname): if len(self.ary_record_pitch) > 0 : with open(fname, "w") as fh: writer = csv.writer(fh, lineterminator="\n") writer.writerows(self.ary_record_pitch) #------------------------------------------------------------ # 1選手の打者記録をCSVファイルに出力 def output_record_to_csv_file_bat(self, fname): if len(self.ary_record_bat) > 0 : with open(fname, "w") as fh: writer = csv.writer(fh, lineterminator="\n") writer.writerows(self.ary_record_bat) #------------------------------------------------------------ # 1選手の記録を収集 def get_record(self): try: resp = urllib.request.urlopen(self.url) except urllib.error.HTTPError as e: print("HTTP-Error : ", e.code) return False except urllib.error.URLError as e: print("URL-Error : ", e.reason) return False else: self.ary_record_pitch = [] self.ary_record_bat = [] bs = BeautifulSoup(resp.read(), "html.parser") for div in bs.findAll("div",id="registermaintbl"): th = div.find(text="防") for tr in div.findAll("tr",class_="registerStats"): ary_1_record = [] for td in tr.findAll("td"): ary_1_record.append(td.get_text()) if th == None : self.ary_record_bat.append(ary_1_record) else: self.ary_record_pitch.append(ary_1_record) return True #//////////////////////////////////////////////////////////////// def get_player_list_detail( resp ): ary_cPlayer = [] bs = BeautifulSoup(resp.read(), "html.parser") # find name for tr in bs.findAll("tr",{"class":"rosterPlayer"}): td = tr.find("td",{"class":"rosterRegister"}) a = td.find("a") if a == None : continue url = a.attrs["href"] name = a.get_text() cPlayer = NpbPlayer(name, url) ary_cPlayer.append(cPlayer) return ary_cPlayer #//////////////////////////////////////////////////////////////// def get_player_list( team_url ): try: resp = urllib.request.urlopen(team_url) except urllib.error.HTTPError as e: print("HTTP-Error : ", e.code) return None except urllib.error.URLError as e: print("URL-Error : ", e.reason) return None else: ary_cPlayer = get_player_list_detail(resp) return ary_cPlayer #//////////////////////////////////////////////////////////////// def generate_record_file_for_1team( team_url, prefix ): ary_cPlayer = get_player_list(team_url) for cPlayer in ary_cPlayer: if True == cPlayer.get_record(): print("now generating %s" % cPlayer.name) cPlayer.output_record_to_csv_file_bat( "./da/data_%s_%s_da.txt" % (prefix, cPlayer.name)) cPlayer.output_record_to_csv_file_pitch("./pt/data_%s_%s_pt.txt" % (prefix, cPlayer.name))
3. 備忘録
python3では reload()が使えなくなった。
同じことを以下のように実現できる。
import importlib importlib.reload(lib_npb)
シーズン中は日々成績が変化するので、ときどき以下を実行して最新情報を収集する。
import lib_npb lib_npb.generate_record_file_for_1team("http://npb.jp/bis/teams/rst_c.html", "C") lib_npb.generate_record_file_for_1team("http://npb.jp/bis/teams/rst_g.html", "G") lib_npb.generate_record_file_for_1team("http://npb.jp/bis/teams/rst_db.html", "DN") lib_npb.generate_record_file_for_1team("http://npb.jp/bis/teams/rst_t.html", "T") lib_npb.generate_record_file_for_1team("http://npb.jp/bis/teams/rst_s.html", "Y") lib_npb.generate_record_file_for_1team("http://npb.jp/bis/teams/rst_d.html", "D") lib_npb.generate_record_file_for_1team("http://npb.jp/bis/teams/rst_h.html", "H") lib_npb.generate_record_file_for_1team("http://npb.jp/bis/teams/rst_f.html", "F") lib_npb.generate_record_file_for_1team("http://npb.jp/bis/teams/rst_m.html", "M") lib_npb.generate_record_file_for_1team("http://npb.jp/bis/teams/rst_l.html", "L") lib_npb.generate_record_file_for_1team("http://npb.jp/bis/teams/rst_e.html", "E") lib_npb.generate_record_file_for_1team("http://npb.jp/bis/teams/rst_bs.html", "O")