ヘッドレスブラウザ + プロキシ:PuppeteerとPlaywrightの設定ガイド

プロキシ回転、ステルスプラグイン、デバイスエミュレーション、住宅プロキシを使用してパターンをスクレイピングするPuppeteerとPlaywrightを構成するステップバイステップガイド.

ヘッドレスブラウザ + プロキシ:PuppeteerとPlaywrightの設定ガイド

なぜヘッドレスブラウザはプロキシが必要なのか

ヘッドレスブラウザ — ブラウザインスタンスが表示されていない GUI を実行している場合 — JavaScript-heavy サイトをスクレイピングするのに不可欠です。 しかし、単一のIPアドレスから複数のヘッドレスブラウザセッションを実行することは、明らかな自動化信号です。 ヘッドレスブラウザをプロキシ回転と組み合わせることで、数千もの住宅用IPを介したリクエストを配信できます。

このガイドは、PuppeteerとPlaywrightプロキシ構成、ステルスプラグイン、および回転戦略をカバーしています。 検出方法に関する背景については、こちらをご覧ください。 アンチボット検出システムへのガイド. .

Puppeteer プロキシセットアップ

基本構成

// Puppeteer: Basic proxy configuration
const puppeteer = require('puppeteer');
const browser = await puppeteer.launch({
  headless: 'new',
  args: [
    '--proxy-server=http://gate.proxyhat.com:8080',
    '--no-sandbox',
    '--disable-setuid-sandbox'
  ]
});
const page = await browser.newPage();
// Authenticate with the proxy
await page.authenticate({
  username: 'USERNAME',
  password: 'PASSWORD'
});
await page.goto('https://example.com', {
  waitUntil: 'networkidle2',
  timeout: 30000
});
const content = await page.content();
console.log(content.substring(0, 200));
await browser.close();

Puppeteer付きSOCKS5

// Puppeteer: SOCKS5 proxy configuration
const browser = await puppeteer.launch({
  headless: 'new',
  args: [
    '--proxy-server=socks5://gate.proxyhat.com:1080'
  ]
});
const page = await browser.newPage();
await page.authenticate({
  username: 'USERNAME',
  password: 'PASSWORD'
});

Puppeteer Stealth プラグイン

デフォルトのPuppeteer構成は、アンチボットシステムが検出するオートメーションマーカーの数十を公開します。 ザ・オブ・ザ・ puppeteer-extra-plugin-stealth プラグインは、これらのマーカーを自動的にパッチします。

// Install: npm install puppeteer-extra puppeteer-extra-plugin-stealth
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
// Apply stealth plugin
puppeteer.use(StealthPlugin());
const browser = await puppeteer.launch({
  headless: 'new',
  args: [
    '--proxy-server=http://gate.proxyhat.com:8080',
    '--disable-blink-features=AutomationControlled',
    '--window-size=1920,1080',
    '--disable-dev-shm-usage'
  ]
});
const page = await browser.newPage();
await page.authenticate({
  username: 'USERNAME',
  password: 'PASSWORD'
});
// Set realistic viewport
await page.setViewport({ width: 1920, height: 1080 });
// Set extra headers for consistency
await page.setExtraHTTPHeaders({
  'Accept-Language': 'en-US,en;q=0.9'
});
await page.goto('https://example.com');

ステルスプラグインパッチ:

  • navigator.webdriver — 真ではなく未定義に設定
  • chrome.runtime — 不要なChrome固有のオブジェクトを追加します。
  • WebGLベンダー/レンダリング — リアルなGPU文字列
  • プラグインとパーミッションの配列 — 実際のChromeにマッチ
  • 言語とプラットフォームの一貫性

これらのパッチアドレスの深い理解のために、私たちの記事を参照してください ブラウザの指紋. .

Playwright プロキシセットアップ

Playwrightは、Puppeteerよりもエレガントなプロキシ構成を提供します。

基本構成

// Playwright: Basic proxy setup
const { chromium } = require('playwright');
const browser = await chromium.launch({
  proxy: {
    server: 'http://gate.proxyhat.com:8080',
    username: 'USERNAME',
    password: 'PASSWORD'
  }
});
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://example.com');
const title = await page.title();
console.log(`Page title: ${title}`);
await browser.close();

Per-Context プロキシ (タブごとに異なる IP )

// Playwright: Different proxy per context
const { chromium } = require('playwright');
const browser = await chromium.launch();
// Context 1: US proxy session
const ctx1 = await browser.newContext({
  proxy: {
    server: 'http://gate.proxyhat.com:8080',
    username: 'USERNAME-country-us-session-abc1',
    password: 'PASSWORD'
  },
  locale: 'en-US',
  timezoneId: 'America/New_York'
});
// Context 2: UK proxy session
const ctx2 = await browser.newContext({
  proxy: {
    server: 'http://gate.proxyhat.com:8080',
    username: 'USERNAME-country-gb-session-abc2',
    password: 'PASSWORD'
  },
  locale: 'en-GB',
  timezoneId: 'Europe/London'
});
const page1 = await ctx1.newPage();
const page2 = await ctx2.newPage();
// Each page uses a different IP and locale
await page1.goto('https://example.com');
await page2.goto('https://example.com');

プロキシによるデバイスエミュレーション

// Playwright: Realistic device emulation + proxy
const { chromium, devices } = require('playwright');
const browser = await chromium.launch({
  proxy: {
    server: 'http://gate.proxyhat.com:8080',
    username: 'USERNAME',
    password: 'PASSWORD'
  }
});
// Emulate a specific device with matching settings
const context = await browser.newContext({
  ...devices['Desktop Chrome'],
  locale: 'en-US',
  timezoneId: 'America/Chicago',
  geolocation: { latitude: 41.8781, longitude: -87.6298 },
  permissions: ['geolocation'],
  colorScheme: 'light'
});
const page = await context.newPage();
await page.goto('https://example.com');

Headlessブラウザでプロキシ回転

戦略1:要求ごとの新しいコンテキスト

URLごとに新しいブラウザのコンテキストを作成します。 これは、要求ごとに新しいIPとクリーンクッキーを与えます。

// Playwright: Rotate proxy per request via new contexts
async function scrapeWithRotation(urls) {
  const browser = await chromium.launch();
  const results = [];
  for (const url of urls) {
    const sessionId = `sess-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
    const context = await browser.newContext({
      proxy: {
        server: 'http://gate.proxyhat.com:8080',
        username: `USERNAME-session-${sessionId}`,
        password: 'PASSWORD'
      }
    });
    const page = await context.newPage();
    try {
      await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 30000 });
      const data = await page.evaluate(() => document.title);
      results.push({ url, data });
    } catch (error) {
      console.error(`Failed: ${url} — ${error.message}`);
    } finally {
      await context.close();
    }
    // Natural delay between requests
    await new Promise(r => setTimeout(r, 1000 + Math.random() * 2000));
  }
  await browser.close();
  return results;
}

戦略2:マルチページフローの粘着セッション

複数のページ(ペジネーション、ログインフロー)で同じIPを維持する必要がある場合は、スティッキーセッションを使用します。

// Playwright: Sticky session for multi-page scraping
async function scrapeWithStickySession(baseUrl, pageCount) {
  const sessionId = `sticky-${Date.now()}`;
  const browser = await chromium.launch({
    proxy: {
      server: 'http://gate.proxyhat.com:8080',
      username: `USERNAME-session-${sessionId}`,
      password: 'PASSWORD'
    }
  });
  const context = await browser.newContext();
  const page = await context.newPage();
  const results = [];
  for (let i = 1; i <= pageCount; i++) {
    await page.goto(`${baseUrl}?page=${i}`, { waitUntil: 'networkidle' });
    const items = await page.$$eval('.item', els =>
      els.map(el => el.textContent.trim())
    );
    results.push(...items);
    // Natural delay between pages
    await new Promise(r => setTimeout(r, 1500 + Math.random() * 1500));
  }
  await browser.close();
  return results;
}

戦略3:プールとの同時スクレイピング

// Playwright: Concurrent scraping with proxy pool
async function concurrentScrape(urls, concurrency = 5) {
  const browser = await chromium.launch();
  const results = [];
  // Process URLs in batches
  for (let i = 0; i < urls.length; i += concurrency) {
    const batch = urls.slice(i, i + concurrency);
    const promises = batch.map(async (url) => {
      const sessionId = `conc-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
      const context = await browser.newContext({
        proxy: {
          server: 'http://gate.proxyhat.com:8080',
          username: `USERNAME-session-${sessionId}`,
          password: 'PASSWORD'
        }
      });
      const page = await context.newPage();
      try {
        await page.goto(url, { timeout: 30000, waitUntil: 'domcontentloaded' });
        return { url, title: await page.title(), status: 'ok' };
      } catch (e) {
        return { url, error: e.message, status: 'error' };
      } finally {
        await context.close();
      }
    });
    const batchResults = await Promise.all(promises);
    results.push(...batchResults);
    // Delay between batches
    await new Promise(r => setTimeout(r, 2000));
  }
  await browser.close();
  return results;
}

Python(Pyppeteerオルタナティブ)のPuppeteer

Python開発者向け、 playwright Python はクリーナーの構文と同じ機能を提供します。

# Python: Playwright with proxy and stealth settings
# pip install playwright
# playwright install chromium
from playwright.async_api import async_playwright
import asyncio
async def scrape_with_proxy():
    async with async_playwright() as p:
        browser = await p.chromium.launch(
            proxy={
                "server": "http://gate.proxyhat.com:8080",
                "username": "USERNAME",
                "password": "PASSWORD"
            }
        )
        context = await browser.new_context(
            viewport={"width": 1920, "height": 1080},
            locale="en-US",
            timezone_id="America/New_York",
            user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
        )
        page = await context.new_page()
        await page.goto("https://example.com")
        title = await page.title()
        print(f"Title: {title}")
        await browser.close()
asyncio.run(scrape_with_proxy())

資源の最適化

ヘッドレスブラウザは重要なメモリとCPUを消費します。 生産のワークロードのためにを最大限に活用して下さい:

不要なリソースをブロック

// Playwright: Block images, fonts, and CSS to save bandwidth
const context = await browser.newContext({
  proxy: {
    server: 'http://gate.proxyhat.com:8080',
    username: 'USERNAME',
    password: 'PASSWORD'
  }
});
const page = await context.newPage();
// Block non-essential resources
await page.route('**/*.{png,jpg,jpeg,gif,svg,webp,woff,woff2,ttf,css}', route =>
  route.abort()
);
// Block tracking and analytics
await page.route('**/{google-analytics,gtag,facebook}**', route =>
  route.abort()
);
await page.goto('https://example.com');

メモリ管理

  • 使用後のコンテキストを閉じる: 各オープンコンテクストは50-150MBを消費します。 実行時に常にコンテキストを閉じます。
  • 同時コンテキストを制限する: 利用可能なRAMに基づいて、ブラウザインスタンスごとに3-10コンテキストを保持します。
  • 定期的にブラウザを再起動: 100-200のコンテキストサイクルの後、ブラウザを再起動してメモリリークを防ぎます。
  • headless を使う: 'new' (Puppeteer): 新しいヘッドレスモードは、古いものよりも少ないメモリを使用します。

共通の問題の処理

プロキシ認証失敗

// Handle proxy auth errors gracefully
try {
  const response = await page.goto(url, { timeout: 30000 });
  if (response.status() === 407) {
    console.error('Proxy authentication failed — check credentials');
  }
} catch (error) {
  if (error.message.includes('net::ERR_PROXY_CONNECTION_FAILED')) {
    console.error('Proxy connection failed — check proxy server availability');
  }
}

タイムアウト処理

// Retry with exponential backoff
async function gotoWithRetry(page, url, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await page.goto(url, {
        waitUntil: 'domcontentloaded',
        timeout: 30000
      });
    } catch (error) {
      if (attempt === maxRetries) throw error;
      const delay = 1000 * Math.pow(2, attempt) + Math.random() * 1000;
      console.log(`Retry ${attempt}/${maxRetries} after ${delay}ms`);
      await new Promise(r => setTimeout(r, delay));
    }
  }
}

ベストプラクティスチェックリスト

ベストプラクティスチェックリスト
トレーニングパプピータープレイライト
コンテキストプロキシ打ち上げラグのみコンテキストプロキシサポート
ステルスパッチpuppeteer-extra-plugin-stealth(パプテ)内蔵デバイスエミュレーション
リソースブロックページ.setRequestInterceptionサイトマップ
マルチブラウザクロムのみクロム、Firefox、WebKit
セッションの分離セッションごとの新しいブラウザセッションごとの新しいコンテキスト
ほとんどのスクレイピングタスクでは、Playwrightは、優れたプロキシサポート(per-context)、組み込みデバイスエミュレーション、マルチブラウザのサポートにより、Puppeteerよりも推奨される選択肢です。 組み合わせて ProxyHatの住宅用プロキシ 最良の結果を得るために。

ヘッドレスブラウザなしで言語固有のプロキシ設定については、ガイドを参照してください フィードバック, ノード.jsおすすめ. 広範囲の反検出の作戦のために、私達を読んで下さい 検出低減ガイド. 常に倫理的なスクレイピングの実践と尊重に従う ウェブサイトアクセスポリシー. .

よくある質問

始める準備はできましたか?

AIフィルタリングで148か国以上、5,000万以上のレジデンシャルIPにアクセス。

料金を見るレジデンシャルプロキシ
← ブログに戻る