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

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

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

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

Python 3.x

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

Q&A

解決済

5回答

10623閲覧

netkeiba.comのレース情報が新しくなったため、スクレイピングが出来なくなり苦慮しております。

akakage13

総合スコア89

スクレイピング

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

Python 3.x

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

0グッド

1クリップ

投稿2020/01/17 07:36

python3.5、windows10を使用しております。

netkeiba.comよりレース情報をスクレイピングしております、
先週まで、動いていたプログラムが機能しなくなり苦慮しております。

# -*- coding:utf-8 -*- import urllib.request import codecs import time from bs4 import BeautifulSoup #京都競馬場レース情報 f1 = codecs.open('kyoto1.csv', 'w', 'utf-8') f1.write('type,race_number,other_race_name,other_race_name_2,tousuu,race_name,race_condition,horse_number,horse_name,sex_age,jockey_name,kinryo,odds,pop'+u"\n") url_1='http://oldrace.netkeiba.com/?pid=race_old&id=c202008010601' #race1 tr_arr_1 = soup_1.select("table.race_table_old nk_tb_common > tr ") for tr_1 in tr_arr_1: #time.sleep(0.25) tds_1 = tr_1.findAll("td") if len( tds_1 ) > 1: horse_number_1=tds_1[1].text #馬番 horse_name_1=tds_1[3].a.text #馬名 sex_age_1=tds_1[4].text #性齢 jockey_name_1=tds_1[6].a.text #騎手   kinryo_1=tds_1[5].text #斤量 odds_1=tds_1[8].text #オッズ pop_1=tds_1[9].text #人気 type_1 = "1" race_number_tag_1 = soup_1.find('div',{'class':'mainrace_data fc'}).find('dt') race_number_1 = "".join([x for x in race_number_tag_1.text if not x == u'\xa0' and not x == u'\n']) race_name_tag_1 = soup_1.find('div',{'class':'mainrace_data fc'}).find('h1') race_name_1 = "".join([x for x in race_name_tag_1.text if not x == u'\xa0' and not x == u'\n']) race_condition_tag_1 = soup_1.find('div',{'class':'mainrace_data fc'}).find('p') race_condition_1 = "".join([x for x in race_condition_tag_1.text if not x == u'\xa0' and not x == u'\n']) other_race_name_tag_1 = soup_1.find('div',{'class':'race_otherdata fc'}).find('p') other_race_name_1 = "".join([x for x in other_race_name_tag_1.text if not x == u'\xa0' and not x == u'\n']) d_1 = soup_1.find('div',{'class':'race_otherdata'}) for p_1 in d_1.find_all('p'): t_1 = p_1.text.replace(u'\xa0', ',') # 「 」(NO-BREAK SPACE)=\xa0を分かりやすい区切り文字に置換 cols = [type_1.strip(),race_number_1.strip(),other_race_name_1.strip(),t_1.strip(),race_name_1.strip(),race_condition_1.strip(),horse_number_1.strip(),horse_name_1.strip(),sex_age_1.strip(),jockey_name_1.strip(),kinryo_1.strip(),odds_1.strip(),pop_1.strip()] f1.write(",".join(cols) + "\n") print (race_number_1.strip()) f1.close()

上記のソースコードは先週まで動いていたソースコードです。

これは京都1Rですが、実際には12Rまでソースコードを数字を変えて繰り返しております。
便宜上、1レースのみコードをのせています。

なにかエラーメッセージでもでると調べて直そうと思うのですが、エラーメッセージも出ません。
ただ、空のcsvデータをはきだすだけです。

併せて、今回netkeiba.comは新旧のレース情報を同時に掲載しております

https://oldrace.netkeiba.com/?pid=race_old&id=c202008010601

これは私が使っていますもので

https://race.netkeiba.com/race/shutuba.html?race_id=202008010601&rf=race_list

これが、新しいウェブリストです。

先週まで動いていたソースコードが旧型のアドレスで動かないことが
とても疑問に思います。

ソースコードも自分なりに調べてみましたが、エラーメッセージがでないので、自分としては
ここまでと思い、投稿させていただきました。

御教示をよろしくお願いいたします。

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

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

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

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

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

guest

回答5

0

オッズと人気はjQueryで生成している以外は特に難しくはないはずです。

!apt install chromium-chromedriver !cp /usr/lib/chromium-browser/chromedriver /usr/bin !pip install selenium

python

1from selenium import webdriver 2from selenium.webdriver.chrome.options import Options 3 4options = webdriver.ChromeOptions() 5options.add_argument("--headless") 6options.add_argument("--no-sandbox") 7options.add_argument("--disable-dev-shm-usage") 8 9driver = webdriver.Chrome("chromedriver", options=options) 10driver.implicitly_wait(10) 11driver.get( 12 "https://race.netkeiba.com/race/shutuba.html?race_id=202008010601&rf=race_list" 13) 14 15html = driver.page_source.encode("utf-8") 16 17import pandas as pd 18 19df = pd.read_html(html, encoding="utf-8", skiprows=1, header=0)[0] 20 21df

投稿2020/01/17 14:27

編集2020/01/17 23:57
barobaro

総合スコア1286

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

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

akakage13

2020/01/18 23:07

何回もご助言くださりましてありがとうございました。
guest

0

ベストアンサー

プログラムが今まで正しく動作していたとすれば、プログラムで指定している項目がHTMLで見つからないようなので、サイトの HTML 構造が変わっていますね。

サイトの HTML 構造が変わったので、取得できなかったのでしょう。

取得したいのであれば、サイトに合わせてプログラムを変更するしか無いと思います。

スクレイピングは、サイトがリニューアル等で変更されるとそれに合わせてプログラムも修正する必要があることが多いですので、動かなくなった場合は、その都度プログラムを修正して対処することになります。

投稿2020/01/18 04:11

CHERRY

総合スコア25218

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

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

akakage13

2020/01/18 23:05

おっしゃる通りでございます。
guest

0

宿命ではないでしょうか。
私もターゲットサイトが変わるたびシコシコとその対応をしています。これからもそれは変わらないでしょう。
でもその度に若干スキルはアップしている気がします(自己満足ですが)。
BeautifulSoupを調べ適用し、seleniumを調べ適用し、その他いろいろ調べ適用し・・・その繰り返しです。
親の遺言(冗談です)であえて質問者さんのサイトは見ません(見たこともありません)が、「レース情報が新しくなった」とあるのでHTMLが変わっているのでいるのでしょうね。
質問者さんがこれを作った時の気持ちで、HTMLの内容・構造・階層を調べて着実に対応するしかないのではないでしょうか。
できれば、サイトに「以後サイトの構造を変えることは禁止する」と言えれば一番いいですけどね。

投稿2020/01/17 11:55

編集2020/01/17 11:57
ikapy

総合スコア1167

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

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

akakage13

2020/01/18 23:07

おっしゃる通りでございます。
guest

0

馬名だけ試しに取ってますが普通に動きますしプログラムミスがあるのでは?

python

1import requests 2from bs4 import BeautifulSoup 3 4url = "https://race.netkeiba.com/race/shutuba.html?race_id=202008010601&rf=race_list" 5 6headers = { 7 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko" 8} 9 10r = requests.get(url, headers=headers) 11 12r.raise_for_status() 13 14soup = BeautifulSoup(r.content, "html5lib") 15 16for i in soup.select("span.HorseName"): 17 print(i.text)

投稿2020/01/17 11:29

barobaro

総合スコア1286

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

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

akakage13

2020/01/17 11:41

baro baro様 早々のご教示ありがとうございます。 お言葉ではございますが プログラムミスは考えにくいです。 約一年間、WEBのアドレスを変えることだけで 出馬表のスクレイピングが出来ました。 小生としては新旧が混在した今週から 空のcsvを吐き出すだけのプログラムに なりました。 出馬表のみが改変され 他のプログラムは現在も動きます。 エラーメッセージもなく空のcsvしか出ません。 引き続き 御教示よろしくお願いいたします。
guest

0

出先のため詳しいことは分かりませんが、出力が空ということですので、サイトがコンテンツ描画をjavascriptで行うように変更されたのかもしれません。

ブラウザのjavascriptをオフにしてもちゃんと表示されるかどうか確かめてみてはどうでしょうか。

※あくまでひとつの可能性として捉えてください

その場合はseleniumとwebdriverを使用してjavascriptレンダリング後のDOMを取得してからBS4でスクレイピングするという選択肢があります。
(この場合、BS4はなくてもSeleniumの機能でスクレイピングすることは可能です)

投稿2020/01/17 10:01

編集2020/01/17 10:04
kurosuke___

総合スコア217

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

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

akakage13

2020/01/17 10:49

hachi-chan様、早々の御教示ありがとうございます。ご指摘の件ですが、 個々の馬のデータ収集をするプログラムは今でも動くのです。 例えば https://db.netkeiba.com/horse/2016105292?rf=top_pickup このウェブを従来のソースコードでスクレイピングは可能です。 サイトが、出馬表のみを変更することは考えにくいのですが、 また、御教示をよろしくお願いいたします。
kurosuke___

2020/01/18 21:31

ウェブサイトにはサーバーから受け取ったHTMLだけを表示しているものと、そのHTMLに含まれるjavascriptをつかって後からHTMLの要素を生成するものがあります。 urllibやrequests等のみでのスクレイピングの場合はそのjavascriptコードが実行されない、つまり要素が生成されないために、要素が存在しないエラーになるか空の文字列しか取得できないといったことになります。 先に述べた通り、ブラウザのjavascriptをオフにして目的のページを表示させてみてください。 その状態で要素が表示されていなければjavascriptで要素を表示させているページなので現状では取得できません。 その場合はbarobaroさんの回答を参考にすれば取得できます。
kurosuke___

2020/01/18 21:33

barobaroさんがseleniumというライブラリを使用したコードを回答してくださっているのでそちらを参考にしてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問