통합

Shifter와 함께 사용 Puppeteer

몇 분 만에 Shifter의 레지덴셜 프록시를 통해 실제 Chromium 인스턴스를 구동하세요. 네이티브 --proxy-server 지원, page.authenticate(), 탭별 지역 타겟팅, 완전한 클러스터 확장을 제공하며 별도의 플러그인이 필요 없습니다.

빠른 시작

설치

npm install puppeteer

기본 사용법

import puppeteer from "puppeteer";

const browser = await puppeteer.launch({
  args: ["--proxy-server=http://p.shifter.io:443"],
  headless: "new",
});

const page = await browser.newPage();
await page.authenticate({
  username: "customer-USERNAME-country-us-sid-123ABC",
  password: "PASSWORD",
});

await page.goto("https://ipinfo.io/json");
console.log(await page.evaluate(() => document.body.textContent));
// {"ip": "154.16.xxx.xxx", "city": "New York", "country": "US", ...}

await browser.close();

기능

네이티브 --proxy-server 지원, 추가 확장 프로그램이나 사이드카 프로세스가 필요하지 않습니다
page.authenticate()는 headless: 'new' 모드를 포함해 Shifter 자격 증명을 자동으로 처리합니다.
탭별 프록시 자격 증명을 사용하면 하나의 브라우저에서 여러 국가를 병렬로 스크래핑할 수 있습니다
사용자 이름 매개변수를 통한 195개국 이상 Geo 타겟팅 - country, region, city, ASN
puppeteer-cluster, puppeteer-extra-plugin-stealth 및 전체 Puppeteer 플러그인 생태계와 호환
기본값은 요청별 로테이션이며, 스티키 세션에는 `sid`를, N초 동안의 시간제 고정에는 `ttl-N`을 사용합니다

예시

인증된 프록시 + 스티키 세션

`sid-XXX`를 사용자 이름에 추가하여 전체 브라우저 세션 동안 레지덴셜 IP를 고정하세요. 지역 타겟팅을 위해 `country-uk-city-london`을 추가하고, 해당 IP를 300초 동안 유지하려면 `ttl-300`을 추가하세요.

import puppeteer from "puppeteer";
import { randomBytes } from "node:crypto";

const sid = randomBytes(4).toString("hex");

const browser = await puppeteer.launch({
  args: [
    "--proxy-server=http://p.shifter.io:443",
    "--no-sandbox",
    "--disable-blink-features=AutomationControlled",
  ],
  headless: "new",
});

const page = await browser.newPage();
await page.authenticate({
  username: `customer-USERNAME-country-uk-city-london-sid-${sid}-ttl-300`,
  password: "PASSWORD",
});

await page.setUserAgent(
  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
);

// Multi-step flow — every page load reuses the same residential IP.
await page.goto("https://example.co.uk/login", { waitUntil: "networkidle0" });
await page.type("#email", "user@example.com");
await page.type("#password", "secret");
await page.click('button[type="submit"]');
await page.waitForNavigation({ waitUntil: "networkidle0" });

await page.goto("https://example.co.uk/dashboard");
const html = await page.content();
console.log(html.length, "bytes from dashboard");

await browser.close();

탭별 지역 타겟팅

각 새 페이지는 자체 프록시 자격 증명을 받습니다 — 한 탭에서는 미국 사이트를 스크래핑하고 다른 탭에서는 일본 사이트를 스크래핑하되, 모두 하나의 브라우저를 통해 이루어집니다.

import puppeteer from "puppeteer";

const browser = await puppeteer.launch({
  args: ["--proxy-server=http://p.shifter.io:443"],
  headless: "new",
});

async function scrape(country: string, url: string) {
  const page = await browser.newPage();
  await page.authenticate({
    username: `customer-USERNAME-country-${country}-sid-${country}-001`,
    password: "PASSWORD",
  });

  await page.goto(url, { waitUntil: "domcontentloaded" });
  const data = await page.evaluate(() => ({
    title: document.title,
    text: document.body.innerText.slice(0, 200),
  }));

  await page.close();
  return { country, ...data };
}

const results = await Promise.all([
  scrape("us", "https://www.example.com"),
  scrape("jp", "https://www.example.jp"),
  scrape("de", "https://www.example.de"),
  scrape("br", "https://www.example.com.br"),
]);

console.log(results);

await browser.close();

Puppeteer Cluster (병렬 스크래핑)

메모리 부담 없이 수십 개의 페이지로 병렬 확장하세요. puppeteerOptions를 통해 프록시를 전달하고 작업 함수에서 페이지별로 인증하세요.

import { Cluster } from "puppeteer-cluster";

const cluster = await Cluster.launch({
  concurrency: Cluster.CONCURRENCY_PAGE,
  maxConcurrency: 10,
  puppeteerOptions: {
    args: ["--proxy-server=http://p.shifter.io:443"],
    headless: "new",
  },
  monitor: true,
});

await cluster.task(async ({ page, data: url }) => {
  await page.authenticate({
    username: `customer-USERNAME-country-us-sid-${url.replace(/\W+/g, "").slice(0, 8)}`,
    password: "PASSWORD",
  });

  await page.goto(url, { waitUntil: "networkidle0" });
  const title = await page.title();
  const html  = await page.content();

  return { url, title, length: html.length };
});

const urls = [
  "https://example.com/category/laptops",
  "https://example.com/category/phones",
  "https://example.com/category/tablets",
  // ... hundreds more
];

const results = await Promise.all(urls.map((url) => cluster.execute(url)));
console.log(results);

await cluster.idle();
await cluster.close();

스텔스 모드 + 리소스 차단

Shifter를 puppeteer-extra의 stealth 플러그인과 결합하고 이미지 / 폰트 / 미디어를 차단하여 Chrome의 자동화 플래그를 피하면서 5~10배 더 빠르게 스크래핑하세요.

import puppeteer from "puppeteer-extra";
import StealthPlugin from "puppeteer-extra-plugin-stealth";

puppeteer.use(StealthPlugin());

const browser = await puppeteer.launch({
  args: [
    "--proxy-server=http://p.shifter.io:443",
    "--disable-blink-features=AutomationControlled",
  ],
  headless: "new",
});

const page = await browser.newPage();

await page.authenticate({
  username: "customer-USERNAME-country-us-city-newyork-sid-789GHI",
  password: "PASSWORD",
});

// Block images, fonts, and media for faster page loads
await page.setRequestInterception(true);
page.on("request", (req) => {
  const blocked = ["image", "font", "media", "stylesheet"];
  blocked.includes(req.resourceType()) ? req.abort() : req.continue();
});

await page.goto("https://example.com", { waitUntil: "domcontentloaded" });
const products = await page.$$eval(".product", (els) =>
  els.map((el) => ({
    title: el.querySelector("h2")?.textContent?.trim(),
    price: el.querySelector(".price")?.textContent?.trim(),
  })),
);

console.log(products);

await browser.close();
자주 묻는 질문

자주 묻는 질문

Puppeteer와 Shifter 사용에 관한 일반적인 질문.

Pass --proxy-server=http://p.shifter.io:443 to the browser launch args, then call page.authenticate({ username, password }) on each page before navigating. The same proxy applies to every tab and the credentials handle the basic-auth challenge transparently.

예, 최신 Puppeteer(headless: 'new' 사용)에서 가능합니다. 레거시 `headless: true` 모드도 이를 지원합니다. 105 이전 버전의 Chromium에 갇혀 있다면 자격 증명을 주입하는 Chrome 확장 프로그램으로 대체해야 할 수도 있지만, 최근 Puppeteer 릴리스에서는 page.authenticate가 바로 작동합니다.

프록시 사용자 이름에 세션 ID를 추가하세요(예: `customer-USERNAME-country-us-sid-123ABC`). 해당 사용자 이름으로 인증하는 모든 페이지는 동일한 레지덴셜 IP를 공유합니다. `ttl-N`을 추가하면 해당 IP를 최대 N초 동안 고정할 수 있습니다.

예. 각 newPage() 호출은 서로 다른 Shifter 사용자 이름으로 인증할 수 있습니다. 한 탭에는 `country-us`, 다른 탭에는 `country-jp`를 사용하는 식입니다. 브라우저 수준 상태(쿠키, 캐시)는 공유되지만 egress IP는 탭마다 달라지므로, 현지화된 콘텐츠를 병렬로 스크래핑하는 데 이상적입니다.

예. stealth 플러그인은 Chrome의 자동화 지문을 패치하며, Shifter는 레지덴셜 IP를 담당합니다. 두 가지는 깔끔하게 조합됩니다. puppeteer-extra와 stealth 플러그인을 설치한 다음 평소처럼 실행 시 프록시를 설정하세요.

Cluster.launch를 호출할 때 puppeteerOptions에 --proxy-server 인자를 전달한 다음, cluster.task 콜백 내부에서 page.authenticate를 호출하세요. 이를 작업별 고유한 sid와 결합하면 워커 간에 IP를 공유하지 않는 병렬 스크래핑이 가능합니다.

시작하기

Shifter 사용을 함께 시작하기 Puppeteer

Shifter의 205M+ 레지덴셜 및 ISP 프록시를 통해 헤드리스 Chromium을 구동하세요. 네이티브 --proxy-server, 탭별 지역 타겟팅, 고정 세션, 완전한 Puppeteer-cluster 지원을 제공합니다.

Shifter 무료로 체험하기몇 분 만에 설정. 언제든지 취소 가능.