2024年11月9日頃からXで日本最大の競馬情報サービスであるnetkeibaのスクレイピングができなくなった等のポストが何件もされていた。
どのような方法でスクレイピングを行っているかやどのようなエラーが出ているかは不明ですが、私の方で確認したところ、たしかにうまくいかない部分があったのでその回避方法を本記事で説明します。
目次
確認できたエラー
Pythonでrequestとbeautifulsoup4モジュールを組み合わせてnetkeibaのスクレイピングを行うと、以下のエラーが発生しました。

実行したソースコードは以下のとおりです。
from bs4 import BeautifulSoup
import requests
r = requests.get('https://race.netkeiba.com/race/result.html?race_id=202408060411&rf=race_list')
r.raise_for_status()
soup = BeautifulSoup(r.content, 'lxml')これまでは発生しなかったレスポンスステータスコード400のエラーが発生するようになっていました。
回避方法
回避方法は簡単です。
リクエスト時にユーザーエージェントを偽装するだけです。
よくあるのですが、Webサイトによってはプログラムからのアクセスをブロックするためにユーザーエージェントを確認しています。そのようなサイトではプログラムからのアクセスではないというふうに見せかけるためにユーザーエージェントを偽装する必要があります。
ではどのように行うかというと、以下のURLにアクセスし、ブラウザのユーザーエージェントを確認します。
https://testpage.jp/tool/ip_user_agent.php

確認したユーザーエージェントをrequests.get時のheadersに指定するだけです。
from bs4 import BeautifulSoup
import requests
headers = {
'User-Agent': 'Mozilla/5.0 xxxxxxxxxxxxxxxxxxxxxxxxx' # 確認したユーザーエージェントに置換
}
r = requests.get('https://race.netkeiba.com/race/result.html?race_id=202408060411&rf=race_list', headers=headers)
r.raise_for_status()
soup = BeautifulSoup(r.content, 'lxml')以下の記事で紹介した自作モジュールを使用する場合は以下のコードのように指定します。
あわせて読みたい


【Python】requests.getからBeautifulSoupのインスタンス化までの流れを自作モジュール化
私はPythonでrequestとbeautifulsoup4モジュールを組み合わせてWebスクレイピングをすることが多いのですが、コーディング量を減らしたいということでrequests.getからB…
from mybeautifulsoup import MyBeautifulSoup
headers = {
'User-Agent': 'Mozilla/5.0 xxxxxxxxxxxxxxxxxxxxxxxxx'
}
soup = MyBeautifulSoup('https://race.netkeiba.com/race/result.html?race_id=202408060411&rf=race_list', headers=headers)以上のコードの後にスクレイピングの処理を書いていけば問題なく、netkeibaでスクレイピングできると思いますのでぜひやってみてください。


コメント
コメント一覧 (8件)
はじめまして。
競馬予想AIを作りたいと思い、社内のe-learningでPythonをちょっとだけ勉強し、Chat GPTに全面的に依存して何とか予想ができるまでのコードが完成しました。
そのコード、10月の最終週あたりまで普通にnetkeibaのスクレイピングできていたのですが、11月に入ったあたりから全くそれができなくなり、Chat GPTにエラーメッセージを示しながら何とか修復を試みましたが、修復することはできませんでした。
ネットで解決方法のヒントを探している中、貴殿の記事を拝見し、記事の通りに実行したのですが、上手くいきませんでした。
大変に不躾なお願いとは思うのですが、コードをお示しした場合、どこに原因があるのかをご指摘いただくことは可能でしょうか。お力添えいただけますと幸甚です。何卒宜しくお願いします。
管理人さま
ご指摘いただいた部分を記事の通りに、ご指南いただいた通りにコード書き足したら、正常に動作するようになりました!
さすがです!ありがとうございました。悶々と悩んでいたこの2週間は一体なんだったのだろうと思うほど明快に解決しました。
今後とも役に立つ・ためになるブログの執筆を宜しくお願いします。
楽しみにしております。
江戸川コナン様
解決できたということで非常に嬉しく思います。
今後ともよろしくお願いいたします。
コメント失礼いたします。
netkeibaでのスクレイピングが困っており、こちらの記事に辿り着きました。
headersを指定するとたしかにnetkeibaのメイン画面では400エラーは起こらなくなったのですが、for文でrace_idを回すと一定時間経つと読み込まなくなり、seleniumはnetkeibaのメイン画面で停止したままで各レースをうまく読み込めません。
試しにseleniumのウィンドウでnetkeibaのレースとデータベースを開こうとすると400エラーの画面に切り替わります。他のニュースやコラム等は開くことができます。
スクレイピング中のエラー内容を表示させるとHTTP Error 400: Bad Request と表示されます。
困っています。何かお分かりでしたら、ご教示願いたいです。
ぴよ様
恐らく待機処理が必要なところに入っていないためにWebサイト側にブロックされているのだと思います。
修正コードにてしばらくお試しいただければと思います。
proaceさん
お返事が遅くなって申し訳ございません。
先日はありがとうございました。
headersに加えて、待機時間の長さでもブロックをかけられてしまうようで、待機時間を長くしたら無事にできるようになりました。
待機時間が短いと割とすぐに制限をかけられ、待機時間を少し伸ばすと一定時間後に制限をかけられ、待機時間をかなり伸ばすと長時間スクレイピングしても制限をかけられなくなりました。毎週分を更新する程度なら良いのですが、1から過去n年分のデータを取ってくる場合は非常に時間がかかるようですね。
はじめまして。
スクレイピング対策回避の方法を調べていたところこちらのページに行きつきました。
他サイトで申し訳御座いませんが
https://www.2ndstreet.jp/search?category=850063&sortBy=arrival
のサイトをスクレイピングしようとしたところgoodsid、shopidの要素が取得出来ないのですがproace様の方では可能でしょうか?
ユーザーエージェントはランダムで変更する方法を取っておりpythonのrequestsget、httpxを使用しております。
可能でしたらご教示いただきたいです。
恐れ入りますがご検討よろしくお願いいたします。
コメントありがとうございます。
requestsやhttpxでは難しそうですね。
seleniumを使えばできるかと思います。