質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.45%
スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

1回答

2764閲覧

競輪予想のためのスクレイピング(データ収集)

sss8127

総合スコア4

スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

2クリップ

投稿2022/12/19 13:38

前提

Python初心者です。
競輪を予想するためのデータ収集をしようと考え、以下サイトを参考にプログラムを組みました。
https://qiita.com/GOTOinfinity/items/877fc90168d84d8d1297

実現したいこと

とりあえずデータの収集を行いたいので特殊なことは考えていません。

発生している問題・エラーメッセージ

NameError   Traceback (most recent call last) <ipython-input-2-876b8129da46> in <module> 85 return race_results 86 ---> 87 results = scrape_race_result(race_urls, results) 88 89 #各レースデータの行名をレースIDに変更 NameError: name 'results' is not defined

該当のソースコード

from bs4 import BeautifulSoup import requests import tqdm.notebook as tqdm import time import pandas as pd def createURL(month, day): url = 'https://keirin.kdreams.jp/racecard/2021/' + str(month).zfill(2) + '/' + str(day).zfill(2) + '/' return url seedURLs = [ createURL(i, j) for i in range(4, 8, 1) for j in range(1, 30, 1)] print(seedURLs) def get_race_urls(sourceURLs): #URLを格納するための辞書を定義 race_urls = {} #tqdmを使うことでループの進度が表示される for sourceURL in tqdm.tqdm(sourceURLs): try: #リクエストを作成 req = requests.get(sourceURL) #htmlデータを取得 soup = BeautifulSoup(req.content, 'html.parser') #3秒待機 time.sleep(3) #レース情報のページのURLを取得する race_html = soup.find_all('a', class_='JS_POST_THROW') for html in race_html: url = html.get('href') #"一覧"のURL以外を取得 if 'racedetail' in url: race_id = req.sub(r'\D', '', url) race_urls[race_id] = url except: break return race_urls race_urls = get_race_urls(seedURLs) print(race_urls) main_colum = ['予想', '好気合', '総評', '枠番', '車番', '選手名府県/年齢/期別', '級班', '脚質', 'ギヤ倍数', '競走得点', '1着', '2着', '3着', '着外'] result_colum = ['予想', '着順', '車番', '選手名', '着差', '上り', '決まり手', 'S/B', '勝敗因'] def scrape_race_result(race_urls, pre_race_results={}): #取得途中のデータを途中から読み込む race_results = pre_race_results for race_id, url in tqdm.tqdm(race_urls.items()): if race_id in race_results.keys(): continue try: #ページ内ののテーブル(表)のhtmlを取得 main = pd.read_html(url) #レース情報(特徴量データ)のテーブルを取得 df = main[4][:-1] df.columns = main_colum #レース結果(教師データ)のテーブルを取得 result_table = main[-2] result_table.columns = result_colum df_result = result_table.loc[ : , ['着順', '車番']] #文字列型に変換 df = df.astype(str) df_result = df_result.astype(str) #特徴量データと教師データを一つにまとめる df = pd.merge(df_result, df, on='車番', how='left') race_results[race_id] = df #1秒待機 time.sleep(1) except IndexError: print('IndexError: {}', url) continue except KeyError: print('keyerror: {}', url) continue except ValueError: print("ValueError: {}", url) continue except : traceback.print_exc() break return race_results results = scrape_race_result(race_urls, results) #各レースデータの行名をレースIDに変更 for key in results.keys(): results[key].index = [key]*len(results[key]) #全データを結合 race_results = pd.concat([results[key] for key in results.keys()], sort=False)

試したこと

NameError: name 'results' is not defined
ということなので、あらかじめresultsを他の変数で定義 例)result=None など
してscrape_race_result()内でデータを取得できないかと考えましたがうまくいきませんでした。
Pythonは変数がないと宣言ができないと思いますが、この場合の良い対処法などがあればご教授いただきたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

melian

2022/12/19 13:44

pre データはないのでデフォルト値のままでよいのではないでしょうか。 results = scrape_race_result(race_urls)
sss8127

2022/12/19 14:06

コメントありがとうございます。 results = scrape_race_result(race_urls)で実行したところ <ipython-input-12-f59ceb60e6bc> in <module> 92 93 #全データを結合 ---> 94 race_results = pd.concat([results[key] for key in results.keys()], sort=False) 95 96 # print("race_results") ~/opt/anaconda3/lib/python3.8/site-packages/pandas/core/reshape/concat.py in concat(objs, axis, join, ignore_index, keys, levels, names, verify_integrity, sort, copy) 272 ValueError: Indexes have overlapping values: ['a'] 273 """ --> 274 op = _Concatenator( 275 objs, 276 axis=axis, ~/opt/anaconda3/lib/python3.8/site-packages/pandas/core/reshape/concat.py in __init__(self, objs, axis, join, keys, levels, names, ignore_index, verify_integrity, copy, sort) 329 330 if len(objs) == 0: --> 331 raise ValueError("No objects to concatenate") 332 333 if keys is None: ValueError: No objects to concatenate というエラーが出ますね。。
melian

2022/12/19 14:18

辞書にデータフレームが入っている様に見受けられるので、 race_results = pd.concat(results.values()) とするのではないでしょうか。
sss8127

2022/12/19 14:22

そもそも39行目で一覧ページのURLが出力されないのでここを解消しないといけないかもです。。
guest

回答1

0

とりあえず、39行目解消するにはこうですね。
(6行目に1行追加、33行目を修正)

python

1from bs4 import BeautifulSoup 2import requests 3import tqdm.notebook as tqdm 4import time 5import pandas as pd 6import re 7 8def createURL(month, day): 9 url = 'https://keirin.kdreams.jp/racecard/2021/' + str(month).zfill(2) + '/' + str(day).zfill(2) + '/' 10 return url 11 12seedURLs = [ createURL(i, j) for i in range(4, 8, 1) for j in range(1, 30, 1)] 13print(seedURLs) 14 15def get_race_urls(sourceURLs): 16 #URLを格納するための辞書を定義 17 race_urls = {} 18 #tqdmを使うことでループの進度が表示される 19 for sourceURL in tqdm.tqdm(sourceURLs): 20 try: 21 #リクエストを作成 ← レスポンス取得 22 req = requests.get(sourceURL) # ←「req」にはレスポンスが入るので 変数名は「res」とする方が良いでしょう 23 #htmlデータを取得 24 soup = BeautifulSoup(req.content, 'html.parser') 25 #3秒待機 26 time.sleep(3) 27 #レース情報のページのURLを取得する 28 race_html = soup.find_all('a', class_='JS_POST_THROW') 29 for html in race_html: 30 url = html.get('href') 31 #"一覧"のURL以外を取得 32 if 'racedetail' in url: 33 race_id = re.sub(r'\D', '', url) 34 race_urls[race_id] = url 35 except: 36 break 37 return race_urls 38 39race_urls = get_race_urls(seedURLs) 40print(race_urls)

投稿2022/12/20 09:43

odataiki

総合スコア948

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.45%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問