LoginSignup
5
7

More than 3 years have passed since last update.

スクレイピングして前処理してpostgreSQLに書き込む

Posted at

野球のデータを使って分析したいなと思っていつも「サイトの必要な部分をコピーして、excelに張り付けてcsvにして保存」をしていました。がしかし、そろそろ面倒だなと思い、「スクレイピングして前処理してpostgreSQLに書き込む」までをやってみました。

必要なライブラリのインストール

スクレイピングなど


import pandas as pd
from bs4 import BeautifulSoup
import datetime

postgreSQL書きこみ

import psycopg2
from sqlalchemy import create_engine

データの取得

今回は巨人の打者の成績データを「pandas.read_html」で取得します。
ページの表(tableタグ)を順番取ってきてdataframeのリストが返ってくるようです。

raw_data = pd.read_html("https://baseball-freak.com/audience/giants.html", flavor="bs4")

リストが返ってくるので、こんな感じになります
スクレイピング結果.JPG

1つ目のdataframeがこんな感じ。
1つめのdataframe.JPG

2つ目に今回ほしいデータが入っているはずなのでそれを確認

data_set = raw_data[1] # ページ内に複数の表があり、今回ほしいのは2つ目の表なので[1]と指定します
data_set

dataset.JPG

データフレームの内容確認

取得したデータの中身を確認します。

pd.concat(
    [data_set.count().rename('件数'),
    data_set.dtypes.rename('データ型'),
    data_set.nunique().rename('ユニーク件数'),
    data_set.isnull().sum().rename('null件数'),
    (data_set.isnull().sum() * 100 / data_set.shape[0]).rename('欠損の割合 (%)').round(2)],
    axis=1
)

データ調査.JPG

全部がobjectになっているのがわかります。また、先発投手、観客数、試合時間はnullが含まれるようです。

この中で日付、スコア、観客数について型変換などをして分析できるようにします。

日付処理


data_set["月"] = data_set["日付"].replace("月.*$", "", regex=True) # regex:正規表現
data_set["日"] = data_set["日付"].replace("日.*$", "", regex=True).replace("^.*月", "", regex=True)

for i in range(len(data_set['月'])):
    data_set['日付'] = "2019/" +  data_set["月"] + "/" + data_set["日"]

data_set['日付'] = pd.to_datetime(data_set['日付'])
data_set['曜日(数)'] = data_set['日付'].dt.dayofweek
data_set.head()

日付.JPG

観客数の処理

  • 「,」と「人」をreplace
  • fillnaでNaNを0で埋める
  • 型を「int」に変更する
data_set["観客数"] = data_set['観客数'].replace(',', '', regex=True).replace(' 人', '', regex=True).fillna('0').astype(int)
data_set

観客数.JPG

スコアの処理

  • str.splitでスコアを二つに分ける
  • カラムが2つに分かれるので、カラム名を付けて、int型に変換
data_set_score = pd.concat([data_set, data_set['スコア'].str.split(' - ', expand=True)], axis=1)
data_set_score_rename =data_set_score.rename(columns={0:'得点', 1:'失点'})
data_set_score_rename['得点']=data_set_rename['得点'].replace('中止', 0).astype(int)
data_set_score_rename['失点']=data_set_rename['失点'].fillna(0).astype(int)

postgreSQLへの接続


connection_config = {
    'user': '*****',
    'password': '*****',
    'host': '*****',
    'port': '****', # なくてもOK
    'database': '*****'
}

engine = create_engine('postgresql://{user}:{password}@{host}:{port}/{database}'.format(**connection_config))

postgreSQLへ保存

data_set_score_rename.to_sql('giants',schema='baseball_2019', con=engine, if_exists='replace', index=False)

個人的にはここでつまづきました。何につまづいたのかというと、スキーマ名を指定する方法がわからなかったです。公式ドキュメントを読んですぐに解決しましたが、解決するまで1時間くらいかかりました。わからないときってほんと、わかんないですよねー。

以上になります!記載内容で間違いなどありましたら、優しく教えていただけると嬉しいです!

5
7
0

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