LoginSignup
syun000000
@syun000000

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

スクレイピング方法(表形式のデータから、パターンがイレギュラーな場合も含めてすべてキレイにデータを取り出したい)

解決したいこと

スクレイピングにより情報を取得したい。

取得元は以下
https://keirin.kdreams.jp/kawasaki/racedetail/3420240310020001/?pageType=showResult

image.png
このようなデータから

image.png
こういった形でデータを取りたい。

画像は
image.png
の部分からスクレイピングしたもので、これはうまくいっている。

ただし、
image.png
のような場合もあり、必ずしもすべての項目が埋まるわけではない。

また、
image.png
ここの部分は、データが二日分入っている場合、画像のように一日分入っている場合、何も入っていない場合がある。

今のコードでは、三日分のデータが完全にそろっている場合のみスクレイピングできており、それ以外のイレギュラーな場合(「欠」があって着順が入っていない場合や、今場所成績の数字)はスクレイピングできない。

イレギュラーな場合でも、取れないところは空欄で、取れるデータは表形式でデータを取れるようにしたい。

発生している問題・エラー

エラーは出ていない。イレギュラーな場合、情報が取得されない(一つイレギュラーがあるだけで、その枠すべての情報がとれない

該当するソースコード

# 正規表現を使用して文字列aから情報を抽出し、columns_1のカラム名に合わせたデータフレームを作成する関数

import pandas as pd
import re

def create_dataframe_from_a(a):
    # 正規表現パターンを定義
    pattern = re.compile(
        r'(?P<開催場>\w+) (?P<レースグレード>\w+)\s+(?P<日付1>\d+/\d+)(?P<種目1>[^\d]+)(?P<着順1>\d+)着(?P<上り1>\d+\.\d+).*?'
        r'(?P<日付2>\d+/\d+)(?P<種目2>[^\d]+)(?P<着順2>\d+)着(?P<上り2>\d+\.\d+).*?'
        r'(?P<日付3>\d+/\d+)(?P<種目3>[^\d]+)(?P<着順3>\d+)着(?P<上り3>\d+\.\d+).*'
    )

    # テキストから情報を抽出
    match = pattern.search(a)
    if match:
        # マッチした情報を辞書に格納
        data = match.groupdict()

        # DataFrameのカラム名とデータの対応を作成
        columns = [
            '前場所開催場', '前場所レースグレード',
            '前場所1日目日付', '前場所1日目種目', '前場所1日目着順', '前場所1日目上り',
            '前場所2日目日付', '前場所2日目種目', '前場所2日目着順', '前場所2日目上り',
            '前場所3日目日付', '前場所3日目種目', '前場所3日目着順', '前場所3日目上り'
        ]
        data_values = [
            data['開催場'], data['レースグレード'],
            data['日付1'], data['種目1'].strip(), data['着順1'], data['上り1'],
            data['日付2'], data['種目2'].strip(), data['着順2'], data['上り2'],
            data['日付3'], data['種目3'].strip(), data['着順3'], data['上り3']
        ]

        # DataFrameを作成
        df = pd.DataFrame([data_values], columns=columns)
        return df
    else:
        return pd.DataFrame()

# テスト用の文字列
a_test = df_2["前場所成績_開催場 日付/種目/着順/上り"].iloc[0]

# 関数をテスト
df_created_a = create_dataframe_from_a(a_test)
df_created_a

で出力が
image.png

なお、 a_test の実行結果は
image.png

自分で試したこと

image.png
をスクレイピングしようとして、a_testが

image.png

の時、df_created_aの出力が
image.png
のみとなる。

0

1Answer

スクレイピングは、サイトの管理者に許可を得ているとか、規約に従って専用の API にアクセスしているとかでなければ、迷惑行為になるかもしれないということは認識してますか?

クローラーを作って某図書館サイトにアクセスしたら業務妨害とかで逮捕された事例もありますので、甘く見ない方がいいと思います。

逮捕までいかなくても、被害が深刻な場合は損害賠償の訴訟を受けるかもしれません。

訴訟までいかなくても、アクセス遮断なら Web サーバーの設定で管理者だけの判断で容易に可能なので、多分に可能性はあると思います。帯域ごと遮断され、あなたのやったことで多数の利用者が巻き添えを喰らうことになるかもしれません。

回答するのは迷惑行為の手助けをすることになるかも。

0

Comments

  1. @syun000000

    Questioner

    ご回答いただきありがとうございます。
    他の方々から寄せられているスクレイピングに関する多くの質問にも、同様のアドバイスをいただいていることを確認しております。

  2. もし、サイトの管理者に許可を得ているとか、規約に従って専用の API にアクセスしているとかであれば、最初にその旨質問に書いてはいかが? そうでなければ、質問するべきではないと思いますけど。

Your answer might help someone💌