FC今治のゴール集計・先取点

!pip install lxml
!apt install fonts-ipafont-gothic

!rm /content/.cache/matplotlib/fontList.json

"""再起動"""

import time
import csv
import requests
from bs4 import BeautifulSoup

# 試合数
n = 10 + 1

with open('fcimabari_goal.tsv', 'w') as fw:

    writer = csv.writer(fw, dialect='excel-tab', lineterminator='\n')
    
    # ヘッダー
    writer.writerow(['節', 'ホーム', 'アウェイ', '時間', 'チーム名', 'スコア', '背番号', '名前'])
    
    for i in range(1, n):

        url = 'http://www.fcimabari.com/team/game/result/JFL180{0:02d}.html'.format(i)
        
        headers = {
            'User-Agent':
            'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko'
        }

        r = requests.get(url, headers=headers)

        if r.status_code == requests.codes.ok:

            soup = BeautifulSoup(r.content, 'lxml')

            home = soup.select_one('table.tableTypeResult > tr:nth-of-type(2) > td:nth-of-type(1)').get_text(strip=True)
            away = soup.select_one('table.tableTypeResult > tr:nth-of-type(2) > td:nth-of-type(3)').get_text(strip=True)

            tables = soup.select_one('table.tableType03')

            for trs in tables.select('tr'):

                temp = []

                for tds in trs.select('td'):

                    temp.append(tds.get_text(strip=True))

                if len(temp) > 0:
                    # 時間の分を削除
                    temp[0] = temp[0].strip('分')
                    

                    writer.writerow([i, home, away] + temp)
                    # print(temp)

        time.sleep(3)

import pandas as pd

df = pd.read_table('fcimabari_goal.tsv', dtype = {'節' : 'int', 'ホーム' : 'object', 'アウェイ' : 'object', '時間' : 'int', 'チーム名' : 'object', 'スコア' : 'object', '背番号' : 'object', '名前' : 'object'})

df

from google.colab import files

df.to_csv('goal_list.csv')
files.download('goal_list.csv')

# 時間・チーム名を抽出
df1 = df.iloc[:, 3:5]

# カウント用にカウントを追加しデーターを1
df1['カウント'] = 1

'''
# FC今治以外を欠測値に書き換え
df1['チーム名'] = df1['チーム名'].where(df1['チーム名'] == 'FC今治')

# 欠測値を敵チームに書き換え
df1.fillna('敵チーム', inplace=True)
df1
'''
# FC今治以外を敵チームに書き換え
df1.loc[df1['チーム名'] != 'FC今治', 'チーム名'] = '敵チーム'

df1.head()

# 時間別ゴール集計
pv = df1.pivot_table(values = 'カウント', index = '時間', columns='チーム名', aggfunc = sum, fill_value = 0)
pv.head()

# 時間1~99の0のデーターフレームを作成
pv2 = pd.DataFrame(data=[[i, 0, 0] for i in range(1,100)], columns=['時間', '敵チーム', 'FC今治'])
pv2.set_index('時間', inplace=True)
pv2

# 0とゴール集計を結合
pv3 = pv2.append(pv)

# 時間後にまとめる
grouped = pv3.groupby(level=0) 

# 最後のデータのみ(ゴール集計)
pv_goal = grouped.last() 
pv_goal

#時間別ゴールグラフ
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'IPAPGothic'

pv_goal[::-1].plot.barh(figsize=(5, 20), xticks=[0, 1, 2, 3, 4])

# ゴールタイムランキング
df.sort_values(by=['時間'], ascending=True).reset_index(drop=True).head(10)

from google.colab import files

pv_goal.to_csv('goal.csv')
files.download('goal.csv')

# 先取点
goal_time = df.loc[:, ['節','時間','チーム名']]
goal_time

# 先取点一覧
# goal_time.groupby('節')['時間'].min()

first_goal = goal_time.groupby('節').apply(lambda x: x[x['時間'] == x['時間'].min()])
first_goal

# FC今治の先取点の回数と試合数
print(first_goal['チーム名'].value_counts()['FC今治'], '/', df['節'].max())

# FC今治
df_time = df[df['チーム名']=='FC今治']['時間']

# 相手チーム
# df_time = df[df['チーム名']!='FC今治']['時間']

df_time

# 前半
df_time[df_time <= 48].count()

# 後半
df_time[df_time > 48].count()

# 全体
df_time.count()

df_time.describe()

df_count = df_time.value_counts().sort_index()
df_count

PythonでスクレイピングしてテーブルをCSVに保存

Beautifulsoupの場合

import csv

from bs4 import BeautifulSoup
import requests

url = 'http://www.example.com/'

r = requests.get(url)

if r.status_code == requests.codes.ok:

    soup = BeautifulSoup(r.content, 'html.parser')

    result = [[[td.get_text(strip=True) for td in trs.select('th, td')]
               for trs in table.select('tr')]
              for table in soup.select('table')]

    # 取得テーブル数確認
    print(len(result))

    # 取得テーブルデータ確認
    print(result)

    with open('result.csv', 'w') as fw:
        writer = csv.writer(fw, dialect='excel', lineterminator='\n')

        # 0番目のテーブルを保存(リストの番号を変更する)
        writer.writerows(result[0])

Pandasの場合

import pandas as pd

url = 'http://www.example.com/'
dfs = pd.read_html(url, header=0, index_col=0)

# 取得テーブル数確認
print(len(dfs))

# 取得テーブルデータ確認
print(dfs)

# 結合
# df = pd.concat(dfs)

# 0番目のテーブルを保存(リストの番号を変更する)
dfs[0].to_csv('result.csv')

JFLの試合結果からランキングを作成

import pandas as pd

url = 'http://www.jfl.or.jp/jfl-pc/view/s.php?a=1411&f=2019A001_spc.html'
dfs = pd.read_html(url, skiprows=1, na_values='-')

len(dfs)

df = pd.concat(
    dfs, keys=[i for i in range(1,
                                len(dfs) + 1)], names=['節', '番号'])
df.columns = ['日にち', '時間', 'ホーム', 'スコア', 'アウェイ', 'スタジアム', '備考']
df.drop('備考', axis=1, inplace=True)
df.head(10)

# 欠損値確認
df[df.isnull().any(axis=1)]

# スコアがないものを除去
df1 = df.dropna(subset=['スコア'])

# スコアを分割、スコアを削除、結合
df2 = pd.concat(
    [df1, df1['スコア'].str.split('-', expand=True)], axis=1).drop(
        'スコア', axis=1)

# 名前をホーム得点、アウェイ得点に変更
df2.rename(columns={0: 'ホーム得点', 1: 'アウェイ得点'}, inplace=True)

# ホーム得点、アウェイ得点を文字から整数に変更
df2['ホーム得点'] = df2['ホーム得点'].astype(int)
df2['アウェイ得点'] = df2['アウェイ得点'].astype(int)
df2.dtypes

# ホームの結果のみ
df_home = df2.loc[:, ['ホーム', 'ホーム得点', 'アウェイ得点']].reindex()
df_home.columns = ['チーム名', '得点', '失点']
df_home['戦'] = 'ホーム'
df_home.head()

# アウェイの結果のみ
df_away = df2.loc[:, ['アウェイ', 'アウェイ得点', 'ホーム得点']]
df_away.columns = ['チーム名', '得点', '失点']
df_away['戦'] = 'アウェイ'
df_away.head()

# ホームとアウェイを結合
df_total = pd.concat([df_home, df_away])

# 得失点を計算
df_total['得失点'] = df_total['得点'] - df_total['失点']
df_total.head()


# 勝敗を追加
def win_or_loss(x):
    if x['得点'] > x['失点']:
        return '勝利'
    elif x['得点'] < x['失点']:
        return '敗戦'
    else:
        return '引分'


df_total['勝敗'] = df_total.apply(lambda x: win_or_loss(x), axis=1)

df_total.head()


# 勝点を追加
def win_point(x):
    if x['得点'] > x['失点']:
        return 3
    elif x['得点'] < x['失点']:
        return 0
    else:
        return 1


df_total['勝点'] = df_total.apply(lambda x: win_point(x), axis=1)
df_total.head()

# 得点・失点・得失点・勝点 集計
pv_score = df_total.pivot_table(
    values=['得点', '失点', '得失点', '勝点'], index='チーム名', aggfunc=sum)
pv_score.head()

# 集計用にカウント追加
df_total['カウント'] = 1

# 得点・失点・得失点・勝点 集計
pv_wl = df_total.pivot_table(
    values='カウント',
    index='チーム名',
    columns=['戦', '勝敗'],
    aggfunc=sum,
    fill_value=0)
pv_wl

# 列名変更
pv_wl.columns = ['勝利A', '引分A', '敗戦A', '勝利H', '引分H', '敗戦H']

# 合計追加
pv_wl['勝利'] = pv_wl['勝利H'] + pv_wl['勝利A']
pv_wl['引分'] = pv_wl['引分H'] + pv_wl['引分A']
pv_wl['敗戦'] = pv_wl['敗戦H'] + pv_wl['敗戦A']

# 試合数追加
pv_wl['試合数'] = pv_wl['勝利'] + pv_wl['引分'] + pv_wl['敗戦']

# 確認
pv_wl

df3 = df_total.pivot_table(
    values='勝点', index='チーム名', columns='節', aggfunc=sum, fill_value=0)
df3

df_wp = df3.apply(lambda d: d.cumsum(), axis=1)
df_wp

df4 = df_total.copy()

# 評価値を作成
df4['評価値'] = (df4['勝点'] * 10000) + (df4['得失点'] * 100) + df4['得点']
df4

# 評価値集計
df5 = df4.pivot_table(
    values='評価値', index='チーム名', columns='節', aggfunc=sum, fill_value=0)
df5

# 累計評価値
df_eval = df5.apply(lambda d: d.cumsum(), axis=1)
df_eval

# 累計評価値をランキングに変換
df_chart = df_eval.rank(ascending=False, method='min').astype(int)
df_chart

# 前ランキングとの差分
df6 = df_chart.copy()
df_diff = df6.diff(axis=1).fillna(0)


def arrow_up(x):
    if x > 0:
        return '▼'
    elif x < 0:
        return '▲'
    else:
        return '-'


s1 = df_diff.iloc[:, -1].apply(lambda x: arrow_up(x))
s1.name = '前節'

df7 = pd.concat([pv_score, pv_wl], axis=1).join(s1)

# 評価値を作成
df7['評価値'] = (df7['勝点'] * 10000) + (df7['得失点'] * 100) + df7['得点']

# ランキング
df7['順位'] = df7['評価値'].rank(ascending=False, method='min').astype(int)

# 順位で昇順
df7.sort_values(['順位'], inplace=True)

df7

# チーム名をインデックスから解除
df8 = df7.reset_index()
df_rank = df8.loc[:, [
    '前節', '順位', 'チーム名', '勝点', '試合数', '勝利', '勝利H', '勝利A', '引分', '引分H', '引分A',
    '敗戦', '敗戦H', '敗戦A', '得失点', '得点', '失点'
]]

df_rank

df_rank.to_excel('2019_ranking.xlsx', sheet_name='ランキング', index=False)

Ubuntu Python3環境設定

qiita.com

Python in Visual Studio Code – April 2018 Release - Python

sudo apt install git

sudo apt install python3-pip python3-dev python3-tk python3-venv python3-bs4 python3-requests python3-html5lib python3-lxml jupyter python3-numpy python3-pandas python3-matplotlib python3-seaborn python3-openpyxl black

mkdir workspace
cd workspace

python3 -m venv scraping
source scraping/bin/activate

pip3 install requests
pip3 install beautifulsoup4
pip3 install lxml
pip3 install html5lib
pip3 install black
pip3 install pylint
pip3 install pipenv --user
source ~/.profile

pipenv --three
pipenv lock --pre

pipenv install beautifulsoup4
pipenv install requests
pipenv install html5lib
pipenv install lxml

pipenv install --dev pylint
pipenv install --dev black

pipenv install tensorflow
pipenv install keras
pipenv install jupyter
pipenv install matplotlib
pipenv install seaborn
pipenv install pandas
pipenv install openpyxl


pipenv install selenium
pipenv install --dev flake8
pipenv install --dev pycodestyle
pipenv install --dev pydocstyle

pipenv install --dev autopep8
pipenv install --dev yapf

Pipfile

[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
"beautifulsoup4" = "*"
requests = "*"
"html5lib" = "*"
lxml = "*"
selenium = "*"
tensorflow = "*"
keras = "*"
jupyter = "*"
matplotlib = "*"
seaborn = "*"
pandas = "*"
openpyxl = "*"

[dev-packages]
pylint = "*"
"flake8" = "*"
pycodestyle = "*"
pydocstyle = "*"
"autopep8" = "*"
yapf = "*"

[requires]
python_version = "3.6"

[scripts]
fix = "yapf -i -r ."