クイックアンサー
Puppeteerで認証付きプロキシをどう使いますか?
Chromeを--proxy-server=http://gw.crawlrelay.com:7777で起動し、最初のgotoの前にpage.authenticate({ username, password })を呼び出します。Chromeはフラグに書かれた認証情報を無視します。CrawlRelayのレジデンシャルプロキシはユーザー名から国とスティッキーセッションを読み取り、各ページやコンテキストが独自の出口IPを持てます。トラフィックは$0.50/GBから50 GB単位で課金。KYC不要、仮想通貨払い可能です。
Puppeteerセットアップ概要
| プロキシアドレス | --proxy-server=http://gw.crawlrelay.com:7777はargsで、またはブラウザコンテキスト上でproxyServerとして使用可能 |
|---|---|
| 認証情報 | ナビゲート前にawait page.authenticate({ username, password })を呼び出す |
| セッションを分ける | browser.createBrowserContext({ proxyServer }): セッションごとに一つのコンテキストを使う |
| SOCKS5 | Chromeの認証では不可:HTTPポートを使うこと |
| トラフィック節約 | page.setRequestInterception(true)で画像、フォント、メディアを除外して中断する |
認証付きプロキシを一つ設定するには?
これは最小限のパターンです。try … finallyブロックはナビゲーション失敗時でもChromeを閉じます。サーバー上で孤立したブラウザが溜まるのを防ぐのに重要です。
import puppeteer from "puppeteer";
const browser = await puppeteer.launch({
args: ["--proxy-server=http://gw.crawlrelay.com:7777"],
});
try {
const page = await browser.newPage();
await page.authenticate({ username: "USERNAME-country-us", password: "PASSWORD" });
await page.setRequestInterception(true);
page.on("request", (req) =>
["image", "font", "media"].includes(req.resourceType()) ? req.abort() : req.continue()
);
const res = await page.goto("https://example.com/", { waitUntil: "domcontentloaded", timeout: 60000 });
console.log(res.status(), await page.title());
} finally {
await browser.close();
}一つのブラウザで複数セッションまたは複数国をどう扱う?
セッションごとに一つのブラウザコンテキストを作成してください。コンテキストとはクッキー、キャッシュ、ネットワーク状態が分離されたプロフィールのことです。これにより、あるコンテキストの認証情報が他に漏れません。各コンテキストに国またはセッションIDを含むユーザー名を与えます。
import puppeteer from "puppeteer";
import { randomUUID } from "node:crypto";
const GATEWAY = "http://gw.crawlrelay.com:7777";
const browser = await puppeteer.launch();
async function visit(country, url) {
const session = randomUUID().replaceAll("-", "").slice(0, 10);
const context = await browser.createBrowserContext({ proxyServer: GATEWAY });
try {
const page = await context.newPage();
await page.authenticate({
username: `USERNAME-country-${country}-session-${session}-ttl-20`,
password: "PASSWORD",
});
await page.goto(url, { waitUntil: "domcontentloaded", timeout: 60000 });
return { country, session, ip: await page.evaluate(() => document.body.innerText.trim()) };
} finally {
await context.close();
}
}
try {
const results = await Promise.all([
visit("us", "https://api.ipify.org"),
visit("gb", "https://api.ipify.org"),
]);
console.table(results);
} finally {
await browser.close();
}なぜPuppeteerで407やERR_TUNNEL_CONNECTION_FAILEDが出る?
Chromeが認証情報を送っていないか、間違った情報を送っているからです。次を確認してください:
page.authenticate()はページの最初のgotoの前に呼ばれている。--proxy-serverフラグやproxyServerはスキーム、ホスト、ポートのみで、user:pass@部分は含まない。- ユーザー名のターゲティング部分にタイプミスがないか。curlで先にテストしてください。詳細は407ページ参照]
curlで同じ認証情報が通りPuppeteerで失敗する場合はERR_TUNNEL_CONNECTION_FAILEDもご確認ください。
Puppeteerページでどれくらいトラフィックがかかる?
Chromeがダウンロードするものすべてに課金されます:HTML、スクリプト、スタイル、画像、フォント、ページが呼ぶAPIコールなど。HTTP Archive Web Almanac 2025によると、中央値のページ重量はモバイルで2,164 KB、デスクトップで2,412 KBです。リクエストインターセプトで画像、フォント、メディアをブロックすると数百キロバイトに減り、スクリプトをキャッシュから返すとさらに減ります。必要なページだけにローテーション4Gモバイルプロキシ]を使ってください:4Gモバイルトラフィックは$1.50/GBから5 GB、レジデンシャルプロキシは$0.50/GBから50 GBで課金されます。
Puppeteerとプロキシに関する質問
--proxy-serverにユーザー名とパスワードを入れていい?
いいえ。Chromeは--proxy-serverフラグ内の認証情報を無視し、最初のHTTPSリクエストが407で失敗し、ERR_TUNNEL_CONNECTION_FAILEDで隠されます。フラグにはhttp://host:portだけを入れ、認証情報は新しいページごとにpage.authenticate()で渡してください。
Puppeteerでページ間のIPをどうローテーションする?
各ページを新しいブラウザコンテキストで開くか、セッションIDなしのユーザー名を与えてください。新しいコンテキストは新しい接続を開き、接続ごとに通常異なるレジデンシャル出口IPを取得します。一つのページ内ではChromeが接続を再利用し、同じサイトへのリクエストは接続が閉じるまで出口を共有します。
page.authenticate()はリクエストインターセプトと一緒に使えますか?
はい。Puppeteerがプロキシの認証チャレンジを自動処理し、あなたのインターセプトハンドラーは各リクエストでcontinue()かabort()を呼ぶだけです。最初にauthenticate()をセットアップし、その後にインターセプトを有効にしてください。最初の例を参照。
プロキシと一緒にpuppeteer-extra stealthプラグインを使うべき?
当社は自動化検出回避ツールの文書化やサポートはしていません。これらはサイトの自動訪問者フィルターを回避する目的であり、当社の利用規約に反します。公開ページは節度を持ってレンダリングし、公式APIがある場合はそちらを使いましょう。
PuppeteerはどのChromeをプロキシと使う?
最新のPuppeteerは対応するChrome for Testingビルドをダウンロードし、デフォルトで使用します。プロキシフラグやpage.authenticate()は通常のChromeと同様に動作します。自分のChromeをexecutablePathで指定する場合は最新に保ってください。
レジデンシャルプロキシを経由してPuppeteerを実行する
10 GB用の$5.94、50 GBからの$0.50/GB。