Puppeteerでよくある失敗パターンとして、最初のリクエストは通るのに、後半になると 403 や 429 が返ってきたり、タイムアウトしたり、チャレンジページに飛ばされたりすることがあります。それでも多くの解説記事は、ローテーションプロキシを「2行ほど足せば終わる設定変更」のように扱いがちです。
実際はそんなに単純ではありません。--proxy-server フラグを追加するだけのサンプルと、保守しやすい実運用システムの間には大きな差があります。このガイドでは、ブラウザ全体での切り替え、認証付きゲートウェイ、ブラウザの分割運用や外部リレー、安定したブラウザプロファイル、本番向けのエラーハンドリング、そして「そもそもプロキシ管理が不要なケース」まで、率直に解説します。
ローテーションプロキシとは何か、なぜ Puppeteer で必要なのか
プロキシは、Puppeteer のインスタンスとアクセス先サイトの間に入る中継役です。サイト側から見えるのは、あなたのマシンではなくプロキシの出口 IP です。ローテーションプロキシ は、その出口 IP をプールから順番に切り替えます。リクエストごとだったり、セッションごとだったりします。こうすることで、何千回も同じクライアントから叩かれているように見えるのを防ぎます。
Puppeteer でこれが特に重要なのは、ヘッドレス Chrome が単一 IP から何百件も連続リクエストを送る形が、まさにボット対策に検知されやすい典型例だからです。Cloudflare の公式ドキュメント でも、ヒューリスティック、JavaScript の指紋チェック、機械学習モデル、行動異常検知など、複数レイヤーで同時に検知していることが説明されています。IP を切り替えるのは、そのうちの1レイヤーに対する対策にすぎません。あくまで1つです。
知っておきたいプロキシの種類は3つあります。これらは互換ではありません。
- データセンタープロキシ — 安価で高速、ホスティング事業者由来です。ASN(ネットワークブロック)だけで見てもデータセンターだと分かりやすいため、相手に見つかりやすいです。
- 住宅用プロキシ — 実際の一般家庭向け ISP を経由するため、本物の家庭用回線のように見えます。遅くて高価ですが、現実味はかなり高いです。
- モバイルプロキシ — キャリアネットワークの IP で、通常は最も高価です。モバイル回線としての属性が本当に必要な場合に向いています。
住宅用の出口は、データセンター由来の出口より ASN だけで見抜かれにくいことがありますが、どちらも遮断されないわけではありません。検知率に万能の答えはなく、対象サイト、出口の評判、地域、セッション履歴、ブラウザプロファイル、リクエストの振る舞いによって結果は変わります。
もう1つ混乱しやすい違いがあります。自分で管理する静的な IP リスト(プールを管理し、次の IP を選び、失敗処理も自前で行う)と、backconnect / gateway プロキシ(接続先は1つで、裏側の出口切り替えはプロバイダが行う)は別物です。どちらも有効ですが、複雑さの置き場所が違うだけです。
Puppeteer でローテーションプロキシを使う理由と代表的なユースケース
正直に言うと、必要になるまでは切り替えなくても済むことが多く、必要になった途端に本気で必要になります。
| ユースケース | ローテーションが重要な理由 |
|---|---|
| 商品カタログの価格監視 | 1つの IP から何度もカタログを取得すると、レート制限や評判スコアが蓄積しやすい |
| リード情報の補完 / 連絡先抽出 | 1つの IP からプロフィールを何度も見ると、閲覧ではなくスクレイピングと見なされ、行動検知に引っかかりやすい |
| SERP の取得 | 検索エンジンは IP ベースの制限や CAPTCHA に特に厳しい |
| 競合調査 | 同じドメインを何日も繰り返し取得すると、あなたの IP と cookie 履歴に紐づく指紋が蓄積する |
| コンテンツ集約 | 1ページあたりの価値は低いのにページ数だけ多い、まさにボット検知が狙う通信パターン |
「Amazon は51回目でブロックする」のような、固定で引用できる数字はありません。サイト側は共通の閾値を公開していませんし、制御はエンドポイント、アカウント状態、ASN の評判、通信パターンによって変わります。まずは許可された範囲で最小のリクエストレートから始め、ステータスコードだけでなく内容も検証し、実測と対象サイトのポリシーに照らして必要な場合だけローテーションを追加してください。
Puppeteer における 3 つのプロキシローテーション戦略

多くのチュートリアルはここを飛ばすか、ひどい場合は最も雑なやり方しか示しません。粒度は3段階あり、選び方を間違えると時間を無駄にするか、簡単な作業をやたら複雑にしてしまいます。
| ローテーション方式 | 粒度 | ブラウザ再起動が必要? | 複雑さ | 向いている用途 |
|---|---|---|---|---|
ブラウザ単位(--proxy-server) | ブラウザ1インスタンスにつき1プロキシ | はい | 低 | シンプルで小規模なスクレイピング |
ゲートウェイ管理(proxy-chain + backconnect エンドポイント) | プロバイダ / セッションポリシー単位 | いいえ | 中 | 認証付きローテーションゲートウェイ |
| ブラウザ分割運用または外部リレー | ブラウザシャードまたはリレー規則ごとに1プロキシ | 単一プロセス内での差し替えはなし | 高 | 制御された並列処理と細かいルーティング |
選ぶ前に1点だけ。Puppeteer のネットワークインターセプトの公式ドキュメント でも明言されていますが、setRequestInterception は「リクエストごとにプロキシを切り替える」ためのきれいなスイッチではありません。インターセプトされた各リクエストは、continue / respond / abort のいずれかを明示するまで停止します。真のリクエスト単位のプロキシ制御は、インターセプトハンドラ内で直接プロキシを切り替えるのではなく、proxy-chain のようなローカルで制御可能なゲートウェイを経由させる構成が基本です。後述の Method 3 に進む前に、この点は押さえておいてください。
Puppeteer でローテーションプロキシを設定する手順
難易度: 中級
所要時間: 3つの方法をすべて試して 30〜45分ほど
必要なもの: Node.js 18 以上、npm、プロキシリストまたはプロバイダアカウント(形式: protocol://user:pass@host:port)、および puppeteer、proxy-chain、puppeteer-extra パッケージ
事前準備: 始める前に必要なもの
まずは主要パッケージをインストールします。
npm install puppeteer proxy-chain puppeteer-extra puppeteer-extra-plugin-stealth
プロバイダからプロキシリストを入手し、できれば住宅用プロキシを使ってください。少なくとも、実際のリクエストを投入する前に挙動確認できるテスト用プロキシを数本は用意しましょう。認証情報は環境変数で管理し、直書きは絶対に避けてください。ログに残る URL に埋め込むのもNGです。
Method 1: --proxy-server を使ったブラウザ単位のローテーション
これは多くの人が最初に試す基本形で、理由も明快です。予測しやすいからです。Puppeteer の LaunchOptions では、Chrome のコマンドラインフラグを渡す方法として args が正式に案内されており、--proxy-server は Chromium のネイティブフラグです。
import puppeteer from 'puppeteer';
const proxyPool = [
'http://proxy1.example:8080',
'http://proxy2.example:8080',
'http://proxy3.example:8080',
];
let proxyIndex = 0;
async function scrapeWithRotation(url) {
const proxy = proxyPool[proxyIndex % proxyPool.length];
proxyIndex++;
const browser = await puppeteer.launch({
headless: true,
args: [`--proxy-server=${proxy}`],
});
const page = await browser.newPage();
// プロキシに認証が必要な場合、これはナビゲーション前に実行する必要があります
await page.authenticate({
username: process.env.PROXY_USER,
password: process.env.PROXY_PASS,
});
await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 30_000 });
const content = await page.content();
await browser.close(); // プロキシを切り替える前に閉じる
return content;
}
page.authenticate() は、Puppeteer の公式ドキュメントでも説明されている通り、裏側で request interception を静かに有効化します。小さな性能コストですが、思ったより遅いと感じたときの原因として知っておく価値があります。
期待できる結果: 呼び出しごとに、別のプロキシに紐づいた新しいブラウザが起動します。切り替えるにはブラウザを閉じて再起動するしかなく、その起動コストは避けられません。50ページ程度のスクレイピングなら、ブラウザ起動時間だけで他の2手法よりかなり遅く感じるはずです。
使う場面: 並列性が低いスクリプト、1回限りの取得、速度よりデバッグのしやすさが重要な場合。
Method 2: proxy-chain を使った認証付きローテーションゲートウェイ
Chrome は user:pass@host 形式の認証情報をプロキシ URL に埋め込んだ形では受け付けません。Apify がメンテナンスしている proxy-chain は、ローカルに匿名プロキシを立てて、その先にある認証付き上流へ転送することで、この認証問題を解決します。上流がプロバイダのローテーション / backconnect ゲートウェイであれば、セッションポリシーに応じて、その1つのエンドポイントの裏側で出口 IP が切り替わります。proxy-chain 自体が、既存の Puppeteer ページごとに別プロキシを割り当てるわけではありません。
import puppeteer from 'puppeteer';
import { anonymizeProxy, closeAnonymizedProxy } from 'proxy-chain';
async function scrapeThroughGateway(upstreamProxyUrl, targetUrl) {
const localProxy = await anonymizeProxy(upstreamProxyUrl);
let browser;
try {
browser = await puppeteer.launch({
headless: true,
args: [`--proxy-server=${localProxy}`],
});
const page = await browser.newPage();
await page.goto(targetUrl, { waitUntil: 'domcontentloaded' });
return await page.content();
} finally {
if (browser) await browser.close();
await closeAnonymizedProxy(localProxy, true); // 必ず後始末する
}
}
この finally ブロックは飾りではありません。ローカルプロキシサーバーを放置するとポートが枯渇しますし、匿名化プロキシを閉じ忘れたせいで、夜のうちにファイルディスクリプタを食い尽くしたスクレイパーを私は見たことがあります。proxy-chain は、DNS 問題に 593、接続拒否に 594、認証失敗に 597 といった具体的なエラーコードも返すので、失敗分類にかなり役立ちます。詳細は後で触れます。
使う場面: 認証付きの住宅用 / データセンターゲートウェイで、ローテーションがプロバイダ側のエンドポイントまたはセッション設定によって制御される場合。複数の固定プロキシ ID を同時に扱いたいなら、別々のブラウザプロセス(ブラウザ分割運用)か、専用の外部リレーを使ってください。Puppeteer の標準機能には、ページ単位のプロキシ切り替えはありません。
Method 3: リクエストごとのルーティングには外部リレーが必要
これは最も粒度の細かい方法です。理論上は、ページ内の画像、スクリプト、API 呼び出しのすべてを別々の出口に流すこともできます。ただし実際には最も壊れやすく、ドキュメントも少ない方法です。Puppeteer の request interception は、リクエストのフィルタリングや変更を目的として設計されており、ネットワーク転送先をリクエストごとに差し替える用途には向いていません。
import puppeteer from 'puppeteer';
async function inspectRequests(url) {
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.setRequestInterception(true);
page.on('request', async (request) => {
// 実運用で本当にリクエストごとにプロキシを切り替えるには、
// ブラウザの通信先を途中で差し替えるのではなく、
// ローカルリレー(proxy-chain)を経由させる必要があります。
// Chrome はそれを直接サポートしていません。
// 実際の運用では、ここはリソース種別を絞って abort する用途に使い、
// ブラウザ分割運用やゲートウェイと組み合わせるのが一般的です。
if (['image', 'font', 'stylesheet'].includes(request.resourceType())) {
request.abort();
} else {
request.continue();
}
});
await page.goto(url, { waitUntil: 'networkidle2' });
await browser.close();
}
率直な結論: Puppeteer の setRequestInterception() だけで、真のリクエスト単位 IP 切り替えはできません。そこまで細かい制御が本当に必要なら、Chrome をプログラム可能な外部リレー経由で動かすか、プロキシセッション前提のスクレイピングフレームワークを使うべきです。多くのプロジェクトでは、ブラウザシャードごとに1プロキシを割り当てるか、プロバイダ管理のローテーションゲートウェイを使う方が、運用も監査もずっと簡単です。
完全な検知回避スタック: ローテーションプロキシだけではブロックは防げない
よくある不満が「プロキシを使っているのに、まだブロックされる」です。IP アドレスは、現代のボット対策が評価するシグナルの1つに過ぎません。しかも、それだけ切り替えて他の要素が不自然なままだと、むしろ異常値が強調されることがあります。Windows 上の Chrome を名乗っているのに、Client Hints、タイムゾーン、ロケールが合っていない、というのはその典型です。
レイヤー1: 住宅用ローテーションプロキシ
上で説明した通りです。住宅用の出口はデータセンター由来より現実的に見えることが多いですが、最小プールサイズに万能の基準はありません。IP 数を適当に決めるのではなく、実際のリクエスト量、セッション時間、クールダウン、プロバイダの再利用挙動をもとにサイズを決めてください。
レイヤー2: ヘッドレス Chrome の痕跡を隠す Stealth プラグイン
puppeteer-extra-plugin-stealth は、navigator.webdriver、WebGL の vendor 文字列、Chrome runtime オブジェクトの欠落、その他いくつかの CDP 由来リークを補正します。かなり有用な互換レイヤーですが、プロジェクトの README 自体も、これはいたちごっこであり完全防御はおそらく不可能だと率直に述べています。保証ではなく、土台として使ってください。
レイヤー3: 一貫したブラウザプロファイルと適切な間隔
User-Agent は、ブラウザが返す他の情報と内部的に矛盾しない必要があります。Chrome の User-Agent Client Hints は構造化されたプラットフォーム情報を公開するため、手書きの UA 文字列が実際のプラットフォームと食い違うことがあります。バンドルされている Chrome ビルドが提供する UA を優先し、セッション内では viewport / locale / timezone を安定させ、ページごとに新しい指紋を捏造するのではなく、リクエスト間隔を控えめに保ちましょう。
3つのレイヤーをまとめて起動設定に組み込むとこうなります。
import puppeteer from 'puppeteer-extra';
import StealthPlugin from 'puppeteer-extra-plugin-stealth';
import { anonymizeProxy, closeAnonymizedProxy } from 'proxy-chain';
puppeteer.use(StealthPlugin());
function boundedDelay(minMs = 800, maxMs = 1800) {
return new Promise((r) => setTimeout(r, minMs + Math.random() * (maxMs - minMs)));
}
async function stableProfileScrape(targetUrl, upstreamProxy) {
const localProxy = await anonymizeProxy(upstreamProxy);
let browser;
try {
browser = await puppeteer.launch({
headless: true,
args: [`--proxy-server=${localProxy}`, '--lang=en-US'],
});
const page = await browser.newPage();
await page.setViewport({ width: 1366, height: 768 });
await boundedDelay();
await page.goto(targetUrl, { waitUntil: 'domcontentloaded' });
return await page.content();
} finally {
if (browser) await browser.close();
await closeAnonymizedProxy(localProxy, true);
}
}
これは、競合記事の多くが見せない部分です。プロキシ、stealth、フィンガープリントの乱れ対策を1か所にまとめ、すぐにコピーして調整できる形にしています。
本番向けのエラーハンドリングとプロキシ健全性チェック

多くのチュートリアルは、うまく動いた瞬間に終わります。しかし実際のスクレイピングでは、プロキシが落ちたり、認証が切れたり、対象サイトに途中でレート制限されたりするのは日常茶飯事です。祈るだけでは何も解決しません。
指数バックオフとジッター付きのリトライ
function backoffMs(attempt, base = 1000, cap = 30_000) {
const exponential = Math.min(cap, base * 2 ** attempt);
return Math.floor(exponential * (0.5 + Math.random() * 0.5)); // ジッターで同時再試行の集中を防ぐ
}
async function withRetry(fn, maxRetries = 4) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await fn();
} catch (err) {
if (attempt === maxRetries) throw err;
const delay = backoffMs(attempt);
console.warn(`試行 ${attempt + 1} 回目が失敗: ${err.message}. ${delay}ms 後に再試行します`);
await new Promise((r) => setTimeout(r, delay));
}
}
}
失敗するプロキシを自動でブラックリスト化する
const proxyStats = new Map(); // proxyUrl -> { success, failure }
function recordResult(proxyUrl, success) {
const stats = proxyStats.get(proxyUrl) || { success: 0, failure: 0 };
success ? stats.success++ : stats.failure++;
proxyStats.set(proxyUrl, stats);
}
function isHealthy(proxyUrl) {
const stats = proxyStats.get(proxyUrl);
if (!stats) return true;
const total = stats.success + stats.failure;
if (total < 5) return true; // まだデータ不足
return stats.failure / total < 0.5; // 失敗率が50%を超えたら除外
}
function getHealthyProxy(pool) {
const healthy = pool.filter(isHealthy);
if (healthy.length === 0) throw new Error('利用可能な正常プロキシがプールにありません');
return healthy[Math.floor(Math.random() * healthy.length)];
}
成功 / 失敗だけでなく、エラーの種類を必ず追跡してください。407(認証不備)と 429(レート制限)では、取るべき対応がまったく違います。認証に失敗しているプロキシに対して高速リトライを続けても時間の無駄です。必要なのはプロキシの切り替えではなく、認証情報の見直しです。
Puppeteer における代表的なローテーションプロキシのエラー対処
| エラー | 主な原因 | 対処 |
|---|---|---|
ERR_PROXY_CONNECTION_FAILED | プロキシ停止または到達不能 | プールから外し、次のプロキシで再試行 |
407 Proxy Authentication Required | 認証情報が誤っている、または認証方式が非対応 | page.authenticate() の認証情報を確認、URL 埋め込み認証なら proxy-chain を使う |
TimeoutError | プロキシが遅い、または対象サイトが遮断している | タイムアウトを延長、住宅用プロキシへ切り替え |
403 Forbidden | IP または指紋がフラグ付けされた | プロキシを切り替え + stealth 有効化 + UA をランダム化 |
ERR_TUNNEL_CONNECTION_FAILED | HTTPS トンネルの問題 | CONNECT メソッド対応を確認、proxy-chain のローカルトンネルを試す |
表に入れきれない重要点もあります。200 ステータスが返ってきたからといって成功とは限りません。ソフトブロックでは、正常なステータスコードのまま、ログイン壁やチャレンジ画面などの完全な HTML ページを返すことがよくあります。ステータスだけでなく、実際の内容を検証してください。行き詰まったら、Puppeteer のデバッグガイド にある通り、headless: false で実行し、slowMo を入れ、NODE_DEBUG="puppeteer:*" を設定すると詳細なプロトコルログが取れます。ただし、そのログには機密性の高いリクエストデータが含まれる場合があるので、本番認証情報に対しては流しっぱなしにしないでください。
自前のプロキシローテーション vs プロキシゲートウェイ vs AI 抽出 API
| 観点 | 自前のリストローテーション | backconnect ゲートウェイ(Bright Data, Oxylabs, Decodo) | AI 抽出 API(Thunderbit) |
|---|---|---|---|
| コスト(少量利用) | 低〜中 | GB 単価で中〜高 | 低(無料枠あり、その後は従量制) |
| 信頼性 | 健全性チェック次第 | 高い(プロバイダ管理) | 高い(管理された基盤) |
| 検知回避 | 自作が必要 | 部分的(IP ローテーションのみ) | 標準搭載 |
| 構造化出力 | なし(生 HTML) | なし(生 HTML) | あり(スキーマに沿った JSON) |
| セットアップ時間 | 数時間 | 数分 | 数分 |
| 制御 | 完全 | プロバイダ API の範囲内 | スキーマモデルの範囲内 |
最新のベンダー料金(2026-08-07 時点確認)を見ると、ゲートウェイ型のコスト感がつかめます。Bright Data の住宅用料金 は従量課金とボリュームプランがあり、プロモーションは変動します。Oxylabs は 5 GB で $6/GB、1 TB で $2.50/GB を掲載しています。Decodo(旧 Smartproxy)は 3 GB で $3.75/GB、100 GB で $2.75/GB、さらに $4/GB の従量課金を示しています。Decodo は 1億1500万超の IP プールと 99.92% の成功率も掲げていますが、これらはベンダーの主張であり、独立再現されたベンチマークではありません。
私が実際に使う判断基準はこうです。ページとやり取りする必要がありますか? クリック、スクロール、フォーム入力、ログインセッションの維持が必要なら、Puppeteer とプロキシで作ります。すでにページ上にあるデータだけが欲しいなら、ずっと維持し続けることになるプロキシ基盤を作る前に、抽出 API を検討してください。
Puppeteer + プロキシが過剰になるケース: 代わりに API で構造化データを取る
あるプロジェクトで、商品価格をスプレッドシートに入れるだけなのに、3回目のプロキシ健全性チェック基盤の作り直しをしていたとき、ふと気づきました。こうしたインフラの大半は、本当は開発者の最終目的ではない問題、つまり「ページから生 HTML を取り出す」ために存在しています。本当の目的は構造化データです。HTML はただの面倒な中間形式にすぎません。
Thunderbit の Open API は、抽出をブラウザ自動化の副産物ではなく、主操作として扱います。POST /extract に URL と JSON Schema を渡すと、対応する構造化データが返ってきます。 JS レンダリング、ボット対策、CAPTCHA の処理 はバックエンド側で面倒を見てくれるので、stealth プラグインやプロキシプールを自分でつなぎ込む必要はありません。
curl -X POST https://openapi.thunderbit.com/openapi/v1/extract \
-H "Authorization: Bearer $THUNDERBIT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/product",
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"price": {"type": "number"}
},
"required": ["name", "price"]
}
}'
厳密なスキーマではなく、きれいな Markdown だけが欲しい場合には POST /distill もあります。また、同じスキーマを複数 URL にまとめて適用するバッチ抽出にも対応しています。Thunderbit の現在の API 料金 では、Distill は1ページあたり1ユニット、Extract は1ページあたり20ユニットです。無料枠には 600 の一回限りユニットが含まれているので、導入前の検証には十分です。
Claude、Cursor、または他の MCP 対応クライアントで作業している開発者向けに、Thunderbit は thunderbit_extract と thunderbit_distill を MCP ツールとしても公開しています。これにより、エージェントがタスクの途中でページからデータ取得が必要だと判断したとき、別途スクレイピング工程を挟まずに済みます。MCP 設定を組み込む前に、API リファレンス の最新版を確認してください。ツール名やパラメータはドキュメントの版で変わることがあります。
| 観点 | Puppeteer + ローテーションプロキシ | Thunderbit API |
|---|---|---|
| セットアップの複雑さ | 高い — プロキシプール、ローテーションロジック、stealth、リトライが必要 | 低い — JSON Schema 付きの単一 API 呼び出し |
| ボット対策 | 手動 | 標準搭載 |
| 出力 | 生 HTML(パースが必要) | スキーマに一致した構造化 JSON |
| 保守 | 高い — セレクタが壊れ、プロキシも劣化する | 低い |
| 向いている用途 | カスタム自動化、ログインフロー、ニッチな操作 | 大規模なデータ抽出 |
DIY 方式にも公平に触れておくと、アカウントにログインする、複数ステップのフローをクリックして進める、セッションをまたいで状態を保持する必要がある場合は、抽出 API だけでは置き換えられません。Thunderbit の FAQ でも、対話的なログインフローは現時点で API では未対応だと明記されています。その場合は、Puppeteer + プロキシの方が有利です。ただし、やりたいことが「公開ページ群から、こちらが定義したスキーマに沿ってデータを取る」だけなら、自前のプロキシローテーション基盤を作るのは、必要以上に難しい問題を解いていることになります。コードを極力書きたくないチームなら、Thunderbit Chrome 拡張機能 でも同じ AI ベースの抽出をポイント&クリックで使えます。 ノーコードの Web スクレイピング と本格的な開発環境を比較しているなら、検討する価値はあります。
まとめと重要ポイント
Puppeteer のローテーションプロキシは、1つの技法ではありません。ブラウザ単位のローテーションはシンプルで独立性があります。認証付き backconnect ゲートウェイは、1つのブラウザ全体のエンドポイントの裏で出口を切り替えられます。リクエスト単位の細かい切り替えや同時に別IDを扱うには、ブラウザの分割運用か外部リレーが必要で、request interception だけでは Chrome のネットワーク経路は変えられません。
とはいえ、それだけでは不十分です。プロキシは IP 評判の問題を解決しますが、stealth プラグインとフィンガープリントの一貫性はブラウザシグナルの問題を、ジッターと適切な間隔は行動パターンの問題を解決します。どれか1つでも欠ければ、別の理由で結局ブロック対象になります。
自分で作るなら、まずは proxy-chain のリポジトリ と上のコードから始めてください。多くの有料講座より前に進めます。プロキシ管理を丸ごと省いて、構造化データだけを受け取りたいなら、Thunderbit の API ドキュメント を読んでから、週末を丸ごと健全性チェック基盤の構築に使う前に10分だけ比較してみる価値があります。どちらの道も正当です。大事なのは、チュートリアルが想定している問題ではなく、あなたが本当に抱えている問題を解いているかどうかです。AI がこの分野をどう変えているかをさらに深く知りたいなら、AI web scraping と従来手法の比較もぜひご覧ください。
FAQ
Puppeteer では、どのくらいの頻度でプロキシを切り替えるべきですか?
対象サイトのレート制限がどれだけ厳しいかによります。ボット検知が厳しいサイトでは、ページごと、またはセッションごとに切り替えるのがよいでしょう。寛容なサイトなら、セッションごと、あるいはスクレイピング全体で1つの固定 IP を使うだけで十分な場合もあります。万能の数字はありません。403、429、タイムアウトが出始めたら、それを「より積極的に切り替えるべきサイン」と捉えてください。固定回数に縛られる必要はありません。
Puppeteer のスクレイピングに無料プロキシを使えますか?
技術的には可能ですが、ちょっとしたテスト以上にはおすすめしません。無料のプロキシリストはたいてい遅く、不安定で、しかも既に対象サイトにブラックリスト化されていることが多いです。実運用なら、課金済みプロバイダの住宅用プロキシか、管理型ゲートウェイの方がコストに見合います。
puppeteer-extra-plugin-stealth は、すべてのボット対策に効きますか?
いいえ。プラグインの公式ドキュメント でもその通りです。一般的なヘッドレス Chrome の痕跡はいくつか減らせますが、対象サイトはネットワークの評判、TLS 特性、cookie、Client Hints、行動パターンなども評価できます。プラグインは1つの互換レイヤーであって、保証ではありません。
Puppeteer の proxy-chain と --proxy-server の違いは何ですか?
--proxy-server は Chromium のネイティブ起動フラグで、1つのプロキシ終端をブラウザインスタンス全体に割り当てます。Chrome はそこに埋め込まれた認証情報を受け付けません。proxy-chain は、認証付き上流へのローカル匿名トンネルを作ります。ローテーションは、その後に別の上流で再起動する、プロバイダ管理の backconnect ゲートウェイを使う、あるいは別途設計したリレーを通すことで実現します。proxy-chain がページごとにプロキシを自動割り当てするわけではありません。
ローテーションプロキシだけで完全にブロック回避できますか?
いいえ。これが最もよくある誤解です。Cloudflare の bot management のような現代的な対策は、IP 評判とブラウザ指紋、行動パターン、セッション履歴を組み合わせて判定します。プロキシは IP 評判の問題を解決しますが、それ以外のシグナルでフラグを立てられないように、stealth 設定、一貫したフィンガープリント、自然な間隔も必要です。
詳しく知る


