🎯 カスタマイズ可能で検出回避型のクラウドブラウザ。自社開発のChromiumを搭載し、ウェブクローラーAIエージェント向けに設計されています。👉今すぐ試す
ブログに戻ります

BeautifulSoup 403エラーの解決方法

James Thompson
James Thompson

Scraping and Proxy Management Expert

17-Dec-2025
ざっと見てみましょう

ヘッダーの偽装、プロキシのローテーション、そして高度なボット回避技術を実装することで、BeautifulSoupでの403 Forbiddenエラーを克服し、スムーズなスクレイピングを実現します。

主なポイント

  • 403 Forbiddenエラーは、検出されたボットの特徴に基づくサーバー側のブロックを示しています
  • BeautifulSoupはエラーの原因ではありません - 基本のHTTPリクエストライブラリが拒否を引き起こします
  • User-Agentヘッダーの偽装は、正当なブラウザを模倣し、即時のブロックを減少させます
  • 自宅のプロキシは、本物のデバイスIPにリクエストを分散させ、検出を避けます
  • 現代のウェブサイトでは、複数のバイパス技術を組み合わせた包括的なソリューションが必要です

403エラーの理解

403 Forbiddenレスポンスは、ウェブサーバーがリクエストを受け取ったが、明示的に処理を拒否したことを意味します。404エラーがリソースの欠如を示すのに対し、403は意図的なアクセス拒否を示します。BeautifulSoupでスクレイピングを行う際、このエラーはほぼ常にサーバー側のセキュリティシステムが自動化されたトラフィックを検出することから生じます。

BeautifulSoup自体は、取得後にHTMLコンテンツを解析するだけで403エラーを生成することはありません。基盤となるHTTPライブラリ - 通常はPythonのrequestsライブラリ - が実際のウェブリクエストを行います。そのライブラリのリクエストが適切な認証マーカーを欠く場合、ウェブサイトはそれを疑わしいボット活動として拒否します。

一般的な原因には以下が含まれます:

  • User-Agentヘッダーが欠如: requestsのようなライブラリは自らを「python-requests/2.31.0」として識別し、ボット検出を即座に引き起こします
  • 疑わしいリクエストパターン: 同一のIPアドレスからの迅速な連続リクエストが保護メカニズムを引き起こします
  • 標準ヘッダーが欠如: 正当なブラウザは、Accept、Accept-Language、Refererヘッダーを送信しますが、多くのスクレイパーはこれを省略します
  • IPアドレスのフラグ: データセンターのIPまたは既知のプロキシアドレスが即時に拒否を引き起こします
  • 地理的不一致: 予期しない地理的ロケーションからのリクエストは、より厳しい精査を受けます

解決策1: 偽のUser-Agentヘッダーを設定する

最も簡単な403バイパスは、User-Agentヘッダーを正当なブラウザを模倣するよう設定することです:

python Copy
import requests
from bs4 import BeautifulSoup

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}

url = 'https://example.com'
response = requests.get(url, headers=headers)

if response.status_code == 200:
    soup = BeautifulSoup(response.content, 'html.parser')
    # コンテンツをここで解析します
else:
    print(f"リクエストはステータスコードで失敗しました: {response.status_code}")

このアプローチは、サーバーを欺いて、リクエストがPythonスクリプトではなく、正当なChromeブラウザから来ていると受け入れさせるものです。多くのサイトでは、この単一の変更で403エラーが解消されます。

解決策2: ヘッダー構成を完全にする

ヘッダー情報を拡張することで、リクエストにリアリズムを加えることができます。正当なブラウザは、ウェブサーバーが期待する標準化されたヘッダーの組み合わせを送信します:

python Copy
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language': 'ja-JP,ja;q=0.9',
    'Accept-Encoding': 'gzip, deflate, br',
    'Referer': 'https://www.google.com/',
    'Connection': 'keep-alive',
    'Upgrade-Insecure-Requests': '1'
}

response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.content, 'html.parser')

各ヘッダーは、ブラウザの機能や好みに関するコンテキストを提供します。ウェブサイトは、ヘッダーの組み合わせを分析して整合性を確認します - User-Agentと他のヘッダー間の不一致はボット活動を示します。完全なヘッダーセットは基本的な検出フィルターを通過します。

解決策3: クッキーを使用したセッション管理

一部のウェブサイトでは、クッキーを受け入れる前に初回訪問を経る必要があります。BeautifulSoupはデフォルトではリクエスト間で状態を保持しません。セッションを使用することで、クッキーを保持できます:

python Copy
import requests
from bs4 import BeautifulSoup

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}

session = requests.Session()

# 初回訪問でクッキーを確立
session.get('https://example.com', headers=headers)

# 2回目のリクエストには最初の訪問のクッキーが含まれます
response = session.get('https://example.com/protected-page', headers=headers)
soup = BeautifulSoup(response.content, 'html.parser')

セッションオブジェクトは、リクエスト間でクッキーを自動的に維持し、リターンユーザーの動作をシミュレートします。多くのウェブサイトは、アクセスを許可する前にこのパターンを要求します。

解決策4: リクエスト間の遅延を実装する

連続して迅速にリクエストを送ることは、ボット攻撃のように見えます。リクエスト間に遅延を追加することで、人間のブラウジングを模倣します:

python Copy
import requests
from bs4 import BeautifulSoup
import time

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}

urls = ['https://example.com/page1', 'https://example.com/page2']

for url in urls:
    response = requests.get(url, headers=headers)
    soup = BeautifulSoup(response.content, 'html.parser')
    # コンテンツを処理する
    time.sleep(2)  # リクエスト間に2秒待機

リクエスト間の時間的遅延は、アンチボットシステムに対してより人間らしく見えます。1〜2秒の遅延でも、即座にリクエストを送信した場合と比べて403エラーを大幅に減少させます。

解決策5: レジデンシャルプロキシの統合

Scrapeless Residential Proxiesは、実際の居住者IPにリクエストを分散させ、403エラーの最も一般的な原因—データセンターIPのブロックに対処します。レジデンシャルプロキシは、サーバーファームではなく実際のユーザーデバイスから発信されるため、検出が大幅に難しくなります:

python Copy
import requests
from bs4 import BeautifulSoup

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}

proxy = {
    'http': 'http://username:password@proxy-host:port',
    'https': 'http://username:password@proxy-host:port'
}

response = requests.get(url, headers=headers, proxies=proxy)
soup = BeautifulSoup(response.content, 'html.parser')

スマートローテーションを持つレジデンシャルプロキシは、自動的にIPとヘッダーの分配を行い、手動プロキシ管理を排除します。

解決策6: Seleniumを使ったJavaScriptレンダリング

一部のウェブサイトは、初回のページロード後にJavaScriptを通じてコンテンツを生成します。BeautifulSoupは、レンダリングされたコンテンツなしで空のHTMLスケルトンのみを受け取り、サイトが不完全な解析試行を検出すると、しばしば403エラーをトリガーします。

JavaScriptが多数使用されているサイトに対しては、SeleniumのヘッドレスブラウザがコンテンツをレンダリングしてからBeautifulSoupに渡します:

python Copy
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup

options = Options()
options.add_argument('--headless')
options.add_argument('user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36')

driver = webdriver.Chrome(options=options)
driver.get('https://example.com')

# JavaScriptがレンダリングされるのを待つ
from selenium.webdriver.support.ui import WebDriverWait
WebDriverWait(driver, 10).until(
    lambda driver: driver.find_element('tag name', 'body')
)

html = driver.page_source
soup = BeautifulSoup(html, 'html.parser')
driver.quit()

Seleniumのヘッドレスモードは、正当なブラウザのように動作し、JavaScript検出システムをバイパスしつつ、BeautifulSoupに完全にレンダリングされたHTMLを提供します。

包括的な解決策: Scrapelessアンチボットバイパス

手動のテクニックは基本的なサイトでは機能しますが、Cloudflareのような高度な保護システムでは失敗します。Scrapeless Web Unlockerは、以下の自動処理によって403エラーを処理します:

  • 90M以上のIPを用いたレジデンシャルプロキシのローテーション
  • ダイナミックヘッダー管理とブラウザフィンガープリンティング
  • コンテンツが重いサイト向けのJavaScriptレンダリング
  • 保護されたページのCAPTCHA解決
  • 指数バックオフによる自動リトライ

この統一されたアプローチは、個々のバイパステクニックを積み重ねる試行錯誤のプロセスを排除し、開発を加速させ、成功率を向上させます。

403エラーのデバッグ

403エラーに遭遇したときは:

  1. ブラウザでテスト: Chrome/FirefoxでターゲットURLを開く—通常通りアクセスできれば、サイトは接続を許可しています。
  2. エラーページを確認: 403レスポンスボディには、ブロックの原因に関するヒントが含まれていることがよくあります。
  3. ヘッダーの完全性を確認: すべての標準ヘッダーが現実的な値で存在することを確認します。
  4. 最初にプロキシなしで試す: プロキシがエラーを引き起こした場合、プロキシベースのソリューションに進む前に、直接リクエストをテストします。
  5. レスポンスヘッダーを監視する: サイトは、残りのリクエスト数を明らかにするX-Rate-Limitヘッダーを返すことがよくあります。

予防策

403エラーを繰り返し修正するのではなく、責任ある行動を通じて予防しましょう:

  • robots.txtファイルとサイトのレート制限を尊重する
  • 適切な遅延を設けてリクエストを間隔を空けて送信する
  • 主張したブラウザに一貫した現実的なヘッダーセットを維持する
  • IPをローテーションしてリクエストを複数のソースに分散させる
  • 承認されたデータアクセスのためにサイト管理者に連絡する

よくある質問

Q: なぜスクレイパーは最初は動作するのに、その後突然403エラーを返すのか?

A: 多くのサイトは適応型ブロッキングを実装しており、最初のリクエストを許可した後に、次のリクエストのパターンを検出します。この検出ウィンドウは、通常、数十から数百のリクエストにわたります。トリガーされると、ブロッキングはIPアドレスを変更するか、リクエストの特性を大幅に変更しない限り持続します。

Q: 有料の住宅プロキシの代わりに無料のプロキシを使用できますか?

A: 無料のプロキシは、現代のアンチスクレイピングシステムによって強くブロックされています。ウェブサイトは知られている無料プロキシアドレスのブラックリストを維持しています。有料の住宅プロキシは、無料プロキシが欠く合法性を提供しますが、プレミアムサービスは予算に優しい代替品を大きく上回ります。

Q: すべてのリクエストの間に遅延を追加すべきですか?

A: 各リクエスト間に遅延を追加すると、スクレイピングが非常に遅くなります。その代わりに、一連のリクエストの間に遅延を設けましょう。例えば、最小限の遅延で10件のリクエストを送り、次のバッチの前に2~5秒待ちます。これにより、速度と検出回避のバランスがとれます。

Q: Cloudflare保護サイトは403エラーを返しますか?

A: いいえ—Cloudflareは、検出されたボットを積極的にブロックしている場合に通常403を返しますが、最初にチャレンジページを表示することが多いです(Attention Requiredメッセージからの403)。Scrapelessのドキュメントは、特殊な処理を必要とするCloudflare保護対象について具体的なガイダンスを提供します。

Q: 403保護サイトを合法的にスクレイピングできますか?

A: 合法性はサイトの利用規約とあなたの意図した使用によります。一般に公開データのスクレイピングは合法ですが、利用規約を違反すると責任が発生する可能性があります。スクレイピングを行う前に、サイトの利用規約を必ず確認し、対応策を講じる前に公式なデータアクセスをリクエストすることを検討してください。

Scrapelessでは、適用される法律、規制、およびWebサイトのプライバシーポリシーを厳密に遵守しながら、公開されているデータのみにアクセスします。 このブログのコンテンツは、デモンストレーションのみを目的としており、違法または侵害の活動は含まれません。 このブログまたはサードパーティのリンクからの情報の使用に対するすべての責任を保証せず、放棄します。 スクレイピング活動に従事する前に、法律顧問に相談し、ターゲットウェブサイトの利用規約を確認するか、必要な許可を取得してください。

最も人気のある記事

カタログ