Python requests アクセス権限/許可なしのHTMLコンテンツが返る時
requests.get()のheaders引数にユーザーエージェントを指定すると、正常なHTMLコンテンツが返ってくる可能性がある
まず、例として僕が直面した状況から。
以下のように、requestsでFedexの送料サーチャージを確認するページへgetしたところ、
Pythonimport requests
url = "https://www.fedex.com/ja-jp/shipping/surcharges.html"
response = requests.get(url)
if response.status_code != 200:
print(f"アクセス失敗:Status Code: {response.status_code}")
exit()
html_content = response.text
print(html_content)
こんな↓ふうに、「リクエストを処理できません・アクセス権限がありません」的なhtmlコンテンツがprintされました。
<p class="mainheader1">We're sorry, we can't process your request right now. It appears you don't have permission to view this webpage.</p><BR>
<span>Incident Number: 18.4a55dc17.1692978528.5c8a0495</span>
<br><br><br>
<HR><br><br>
For assistance with your shipping needs, you can call us anytime at <span class="subheader1">1.800.GoFedEx 1.800.463.3339</span> or visit fedex.com.
一部省略していますが、返ってきたコンテンツはこれだけで、Webブラウザでアクセスしたときに見えるコンテンツとは明らかに異なるものです。
これではBeautifulSoupで必要な情報を抜き取ることができません...。
また、requests.get()が失敗しているわけではなく、HTTPステータスコードは正常に"200"が返ってきているうえで「コンテンツは見せないよ」と言われてしまっているのがポイント。
単純なBOT対策がされているっぽいですね。
・・・
とまぁ、こんなとき。
requestsはあきらめて、処理重くなるけどseleniumを使うしかねぇか...?
となるところですが、あきらめる前にヘッダーにユーザーエージェントを付加して試してみる価値はあるかと。
requestsで"アクセス不可/許可なし"的なレスポンスの時の対処法
以下のように、requests.get()のheadersにuser-agentを指定して実行してみます。
Pythonimport requests
user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36'
header = {
'user-agent': user_agent
}
url = "https://www.fedex.com/ja-jp/shipping/surcharges.html"
response = requests.get(url, headers=header)
if response.status_code != 200:
print(f"アクセス失敗:Status Code: {response.status_code}")
exit()
html_content = response.text
print(html_content)
すると、ブラウザで見たときと同様のコンテンツが返ってくるようになり、無事にBeautifulSoupで欲しい情報を抜き取ることができました。
これでも結果は変わらない可能性もありますが、ぼくの場合は目的のサイトで突破できたのでお試しあれ。
ユーザーエージェントのチェック方法
user agent checkとググると検索結果の先頭に現在使用中のブラウザのユーザーエージェントが表示されます。
表示された文字列をすべてコピーし、変数user_agentを置き換えます。
ユーザーエージェントは偽装できるので、上記コードのユーザーエージェントのまま実行しても動作します。