---
title: "تفاوت Puppeteer و Playwright: کدام را انتخاب کنیم؟"
description: "Puppeteer با Node.js مرورگرهای Chrome و Firefox را می‌راند؛ Playwright موتور WebKit، چهار زبان و اجراگر آزمون را می‌افزاید. پروکسی، انتظار و MCP را سنجیدیم."
url: https://proxynet.io/fa/blog/puppeteer-vs-playwright
date: 2026-10-06
author: "Acar Diveroli"
category: "مقایسه, وب اسکرپینگ"
lang: fa
---

# تفاوت Puppeteer و Playwright: کدام را انتخاب کنیم؟

از Node.js به یک مرورگر واقعی نیاز دارید: صفحه‌ای که می‌خواهید بخوانید محتوایش را با JavaScript می‌سازد، یا یک گزارش HTML باید به PDF تبدیل شود. دو نام پیش از همه به میان می‌آیند: Puppeteer و Playwright. هر دو رایگان‌اند و API آن‌ها به هم شبیه است (`page.goto()`، `page.click()`، `page.pdf()`)، پس نحو کد تعیین‌کننده نیست. انتخاب به مرورگرها و زبان‌هایی که لازم دارید، شیوه تنظیم پروکسی و انتظاری که از ابزارهای آزمون و عامل هوش مصنوعی دارید برمی‌گردد.

این نوشته دو ابزار را از نظر مرورگر و پروتکل، زبان‌ها، انتظار، تنظیم پروکسی، ابزارهای آزمون و سرورهای MCP مقایسه می‌کند. یک کار یکسان را با هر دو اجرا کردیم: ⁦Puppeteer 25.12.0⁩ (با ⁦Chrome for Testing 154⁩) و ⁦Playwright 1.63.0⁩ (با ⁦Chromium 153⁩) روی ⁦Node.js 24⁩ و ⁦Windows 11⁩، از راه یک پروکسی محلی که نام کاربری و رمز عبور می‌خواهد. اینکه سایت‌ها کدام ابزار را کمتر تشخیص می‌دهند موضوع این نوشته نیست: هر دو یک مرورگر واقعی را اداره می‌کنند و در هر دو، رعایت قواعد سایت بر عهده شماست.

> **نکته: پاسخ کوتاه**
>
> Puppeteer یک کتابخانه Node.js است که Chrome را از راه Chrome DevTools Protocol و Firefox را از راه WebDriver BiDi اداره می‌کند؛ برای اسکریپتی که فقط با Chrome کار دارد و داده جمع‌آوری می‌کند، تصویر صفحه می‌گیرد یا PDF می‌سازد، همین کافی است. Playwright موتورهای Chromium، Firefox و WebKit را با یک API اداره می‌کند، برای JavaScript، Python، Java و .NET کتابخانه رسمی دارد و همراه با اجراگر آزمون، مولد کد و نمایشگر ردگیری عرضه می‌شود. Playwright نام کاربری و رمز عبور پروکسی را درون گزینه `proxy` برای هر مرورگر یا هر context می‌گیرد؛ Puppeteer نشانی را به شکل آرگومان اجرا یا گزینه context می‌گیرد و اطلاعات ورود را با `page.authenticate()`، که Chrome سپس آن‌ها را برای همان context نگه می‌دارد.

## Puppeteer و Playwright چه هستند؟

Puppeteer یک کتابخانه JavaScript با API سطح بالا برای کنترل Chrome یا Firefox است. روی Node.js اجرا می‌شود و در هیچ زبان دیگری کتابخانه رسمی ندارد؛ نسخه‌های بازنویسی‌شده برای Python وجود دارند، اما پروژه‌هایی شخص ثالث هستند. فرمان `npm i puppeteer` یک ساخت سازگار Chrome for Testing و فایل اجرایی سبک‌تر `chrome-headless-shell` را هم در `~/.cache/puppeteer` دانلود می‌کند، در حالی که `puppeteer-core` همان کتابخانه بدون این دانلود است.

Playwright کتابخانه متن‌باز خودکارسازی Microsoft است. موتورهای Chromium، Firefox و WebKit (موتوری که Safari بر آن ساخته شده) را با یک API اداره می‌کند و برای JavaScript و TypeScript، Python، Java و .NET کتابخانه رسمی دارد. در کنار آن Playwright Test قرار دارد: اجراگر آزمونی با وارسی (assertion) و اجرای موازی. نصب مرورگرها گامی جداگانه است: فرمان `npx playwright install chromium` ساختی را دانلود می‌کند که به نسخه Playwright شما قفل شده است.

هر دو برای صفحه‌هایی هستند که محتوایشان تنها پس از اجرای JavaScript پدیدار می‌شود. اگر داده از پیش در کد منبع صفحه یا در یک نقطه اتصال JSON باشد، یک کلاینت ساده HTTP حافظه بسیار کمتری می‌خواهد.

## هر کدام چگونه با مرورگر گفت‌وگو می‌کند؟

پروتکلی که زیر هر ابزار کار می‌کند بیشتر رفتار آن را توضیح می‌دهد. یک اسکریپت Puppeteer این‌گونه اجرا می‌شود:

1. `puppeteer.launch()` نسخه Chrome for Testing را از حافظه نهان اجرا می‌کند، یا اگر `browser: "firefox"` را بدهید، Firefox را.
2. Puppeteer از راه Chrome DevTools Protocol (CDP)، پروتکل اشکال‌زدایی خود Chrome، یا از راه WebDriver BiDi، استاندارد ⁦W3C⁩ برای خودکارسازی دوسویه مرورگر، به آن وصل می‌شود.
3. هر فراخوانی مانند `page.goto()` به رشته‌ای از پیام‌های پروتکل تبدیل می‌شود.
4. رویدادها بدون آنکه بپرسید بازمی‌گردند: درخواست‌ها، پاسخ‌ها، پیام‌های کنسول و پنجره‌های گفت‌وگو.

[صفحه WebDriver BiDi در مستندات Puppeteer](https://pptr.dev/webdriver-bidi) این تقسیم را توضیح می‌دهد: BiDi برای Firefox پیش‌فرض است، در حالی که Chrome روی CDP می‌ماند، چون هنوز همه قابلیت‌های CDP در BiDi وجود ندارند. از نسخه 23، Puppeteer با نسخه پایدار Firefox کار می‌کند، نه با ساختی ویژه.

Playwright هم با Chromium از راه CDP گفت‌وگو می‌کند. برای Firefox و WebKit ساخت‌های وصله‌خورده خودش را عرضه می‌کند و مستنداتش می‌گوید چون به این وصله‌ها تکیه دارد، با نسخه‌های برند Firefox و Safari کار نمی‌کند؛ Google Chrome و Microsoft Edge از راه گزینه `channel` در دسترس‌اند. در Python، Java و .NET هر فراخوانی از درایور Node.js که همراه بسته آمده است می‌گذرد، پس سمت مرورگر در هر زبان یکسان رفتار می‌کند. برای خودکارسازی همان Firefox که کاربرانتان نصب می‌کنند Puppeteer نزدیک‌تر است؛ WebKit را تنها Playwright دارد.

## Puppeteer در برابر Playwright: جدول مقایسه

| | Puppeteer | Playwright |
|---|---|---|
| مرورگرها | Chrome و نسخه پایدار Firefox | Chromium، Firefox وصله‌خورده و WebKit؛ Chrome و Edge با `channel` |
| پروتکل | CDP برای Chrome، WebDriver BiDi برای Firefox | CDP برای Chromium؛ Firefox و WebKit با ساخت‌های وصله‌خورده |
| زبان‌های رسمی | JavaScript و TypeScript | JavaScript و TypeScript، Python، Java و .NET |
| انتظار | locator پیش از کنش صبر می‌کند | locator پیش از کنش صبر می‌کند؛ وارسی‌های آزمون دوباره تلاش می‌کنند |
| اجراگر آزمون | درون‌ساخت ندارد | Playwright Test |
| ضبط | خروجی Recorder در Chrome DevTools | `playwright codegen` |
| بازبینی یک اجرا | ردگیری کارایی برای DevTools | Trace Viewer |
| پروکسی برای هر مرورگر | آرگومان اجرای `--proxy-server` | `proxy` در `launch()` |
| پروکسی برای هر context | `proxyServer` در `createBrowserContext()` | `proxy` در `newContext()` |
| نام کاربری و رمز پروکسی | `page.authenticate()` روی یک صفحه، نگه‌داشته برای کل context | فیلدهای `username` و `password` |
| سرور MCP | Chrome DevTools MCP (ساخته‌شده بر Puppeteer) | Playwright MCP |

## یک کار یکسان در دو ابزار چگونه نوشته می‌شود؟

صفحه آزمایشی ما، `shop.test`، صفحه محلی کوچکی است که یک و نیم ثانیه پس از بارگذاری شش کارت محصول را با JavaScript چاپ می‌کند و سپس پیوند «Next» را نشان می‌دهد. کار این است: صفحه را از راه پروکسی‌ای که نام کاربری و رمز عبور می‌خواهد باز کن، نام محصولات را بخوان، روی «Next» کلیک کن و نشانی تازه را بررسی کن. در کد خودتان، نشانی هدفتان را به جای `shop.test` بگذارید.

با Puppeteer:

```js
import puppeteer from "puppeteer";

const URL = "http://shop.test/"; // our local test page; put your target here

const browser = await puppeteer.launch({
  args: ["--proxy-server=http://pr.proxynet.io:8000"],
});
try {
  const page = await browser.newPage();
  await page.authenticate({ username: "user", password: "pass" });
  const response = await page.goto(URL);
  console.log("status:", response.status());
  await page.waitForSelector("div.product"); // the list is drawn by JavaScript
  const names = await page.$$eval("div.product h2", (els) => els.map((el) => el.textContent));
  console.log(names.length, "products, first:", names[0]);
  await Promise.all([
    page.waitForNavigation(),
    page.locator("a.next").click(), // the locator waits until the link can be clicked
  ]);
  console.log(page.url());
} finally {
  await browser.close();
}
```

با Playwright:

```js
import { chromium } from "playwright";

const URL = "http://shop.test/"; // our local test page; put your target here

const browser = await chromium.launch({
  proxy: { server: "http://pr.proxynet.io:8000", username: "user", password: "pass" },
});
try {
  const page = await browser.newPage();
  const response = await page.goto(URL);
  console.log("status:", response.status());
  const products = page.locator("div.product h2");
  await products.first().waitFor(); // count() and allTextContents() do not wait
  const names = await products.allTextContents();
  console.log(names.length, "products, first:", names[0]);
  await page.getByRole("link", { name: "Next" }).click(); // waits on its own
  await page.waitForURL("**/page/2/");
  console.log(page.url());
} finally {
  await browser.close();
}
```

هر دو اسکریپت از راه پروکسی آزمایشی محلی ما همین سه سطر را چاپ کردند:

```text
status: 200
6 products, first: Desk lamp
http://shop.test/page/2/
```

Puppeteer نشانی پروکسی را به شکل آرگومان Chrome و اطلاعات ورود را در فراخوانی جداگانه‌ای می‌گیرد؛ Playwright هر سه را در یک شیء می‌گیرد. Puppeteer کلیک را با `page.waitForNavigation()` جفت می‌کند تا نشانی زودتر از موعد خوانده نشود، در حالی که Playwright پیوند را با نام دسترس‌پذیر آن پیدا می‌کند و منتظر الگوی نشانی می‌ماند.

گزارش پروکسی تفاوت دیگری هم نشان داد. حالت headless پیش‌فرض Puppeteer ساخت کامل Chrome for Testing را اجرا می‌کند و این ساخت از راه پروکسی درخواست‌هایی هم به سرویس‌های Google (`update.googleapis.com`، `accounts.google.com` و دیگران) فرستاد. با `headless: "shell"`، یعنی فایل اجرایی سبک‌تر `chrome-headless-shell`، این درخواست‌ها از میان رفتند؛ headless shell پیش‌فرض Playwright تنها درخواست‌های خود صفحه را فرستاد. اگر هزینه ترافیک را به‌ازای هر گیگابایت می‌پردازید، مانند [پروکسی مسکونی](https://proxynet.io/fa/residential-proxy)، بهتر است این ترافیک پس‌زمینه را در پنل خود بررسی کنید.

## انتظار خودکار در هر کدام چگونه کار می‌کند؟

بیشتر خطاها در صفحه‌های پویا از زمان‌بندی می‌آیند: کد دنبال عنصری می‌گردد که JavaScript هنوز آن را نکشیده است. در کنش‌ها، هر دو ابزار این مسئله را به شیوه‌ای مشابه حل می‌کنند.

در Puppeteer راه توصیه‌شده locator است. پیش از کلیک، locator مطمئن می‌شود که عنصر در ناحیه دید (viewport) است، دیده می‌شود، فعال است و کادر مرزی آن در دو فریم پیاپی انیمیشن ثابت مانده است؛ اگر این شرط‌ها در مهلت صفحه برآورده نشوند، `TimeoutError` پرتاب می‌کند. کدهای قدیمی‌تری که بر پایه `page.$()` و `page.click(selector)` نوشته شده‌اند منتظر پدیدار شدن عنصر نمی‌مانند، برای همین در آن سبک نخست `page.waitForSelector()` فراخوانی می‌شود.

Playwright بررسی می‌کند که عنصر دیده شود، ثابت باشد، بتواند رویدادها را دریافت کند و فعال باشد. دو چیز هم می‌افزاید: locator‌هایی که عنصر را با نقش، برچسب یا متن پیدا می‌کنند و با تغییر نام یک کلاس CSS از کار نمی‌افتند، و در Playwright Test وارسی‌هایی مانند `expect(locator).toHaveText()` که تا برقرار شدن شرط دوباره تلاش می‌کنند.

هنگام خواندن یک فهرست هیچ‌کدام صبر نمی‌کند: `page.$$eval()` و `allTextContents()` هرچه را در آن لحظه روی صفحه است برمی‌گردانند، و به همین دلیل هر دو اسکریپت منتظر نخستین محصول می‌مانند.

## تنظیم پروکسی چه تفاوتی دارد؟

در کار جمع‌آوری داده، بیشترین جدایی دو ابزار همین‌جاست.

در Puppeteer آرگومان `--proxy-server` به کل مرورگر بسته می‌شود. برای پروکسی جداگانه در هر نشست، [مرجع `BrowserContextOptions`](https://pptr.dev/api/puppeteer.browsercontextoptions) گزینه‌های `proxyServer` و `proxyBypassList` را شرح می‌دهد و نام کاربری و رمز عبور را به `Page.authenticate` وامی‌گذارد:

```js
const context = await browser.createBrowserContext({
  proxyServer: "http://pr.proxynet.io:8000",
});
const page = await context.newPage();
await page.authenticate({ username: "user", password: "pass" }); // Chrome caches it for the context
```

همین مرجع می‌افزاید که `page.authenticate()` در پس‌زمینه رهگیری درخواست (request interception) را روشن می‌کند و این ممکن است بر کارایی اثر بگذارد. این فراخوانی روی یک صفحه انجام می‌شود، اما Chrome اطلاعات ورود را برای کل browser context نگه می‌دارد: در آزمون‌های ما، context‌ای که هیچ صفحه‌ای در آن این فراخوانی را انجام نداده بود با `net::ERR_INVALID_AUTH_CREDENTIALS` شکست خورد، در حالی که صفحه‌های بعدی در یک context احراز هویت‌شده بی‌مشکل باز شدند. مدیریت نشست‌ها و بررسی IP خروجی در [راهنمای تنظیم پروکسی در Puppeteer](/fa/blog/puppeteer-proxy) آمده است.

در Playwright شیء `proxy` برای کل مرورگر به `launch()` و برای یک context به `newContext()` داده می‌شود و نام کاربری و رمز عبور فیلدهای آن هستند:

```js
const context = await browser.newContext({
  proxy: { server: "http://pr.proxynet.io:8000", username: "user", password: "pass" },
});
```

[راهنمای شبکه Playwright](https://playwright.dev/docs/network#http-proxy) هر دو شکل را نشان می‌دهد و سرورهای HTTP(S) و SOCKSv5 را می‌پذیرد. چون هر context اطلاعات ورود خودش را دارد، فراخوانی‌ای در سطح صفحه نیست که فراموش شود.

یک رفتار را باید بدانید: وقتی اطلاعات ورود را حذف کردیم، Playwright هیچ خطایی پرتاب نکرد و `page.goto()` پاسخی با وضعیت 407 برگرداند. به جای آنکه یک `goto` بی‌صدا را نشانه بارگذاری صفحه بگیرید، `response.status()` را بررسی کنید. تنظیم کامل در نوشته [Playwright چیست و چگونه با پروکسی استفاده می‌شود؟](/fa/blog/playwright-proxy) آمده است.

سه قاعده Chromium برای هر دو ابزار برقرار است. [سند پروکسی Chromium](https://chromium.googlesource.com/chromium/src/+/HEAD/net/docs/proxy.md) می‌گوید Chrome هیچ روش احراز هویتی را برای SOCKS5 پشتیبانی نمی‌کند، پس SOCKS5 با رمز عبور در Chromium از هیچ‌کدام از دو ابزار کار نمی‌کند؛ از لیست سفید IP استفاده کنید که در سمت ما تا 10 نشانی را می‌پذیرد. Chrome اطلاعات ورودی را هم که درون نشانی پروکسی نوشته شود نمی‌پذیرد: در آزمون Puppeteer ما، `user:pass@` در `--proxy-server` باعث شد ⁦Chrome 154⁩ با `net::ERR_NO_SUPPORTED_PROXIES` شکست بخورد، پس این راه میان‌بر نیست. Chrome همچنین برای نشانی‌های loopback، یعنی نشانی‌هایی که به خود دستگاه برمی‌گردند، از پروکسی استفاده نمی‌کند: در آزمون ما Puppeteer نشانی `127.0.0.1` را مستقیم باز کرد، در حالی که Playwright آن را از راه پروکسی فرستاد، و با `--proxy-bypass-list=<-loopback>` Puppeteer هم از پروکسی استفاده کرد.

اگر می‌خواهید هر context از IP دیگری بیرون برود، به فهرستی از نشانی‌ها در کدتان نیاز ندارید. یک گیت‌وی واحد با [پروکسی چرخشی](https://proxynet.io/fa/rotating-proxy)، IP خروجی را برایتان عوض می‌کند و نشست ثابت (sticky) یک IP را 1 تا 60 دقیقه نگه می‌دارد.

## کدام سرور MCP: Playwright MCP یا Chrome DevTools MCP؟

این مقایسه این روزها بیشتر وقتی پیش می‌آید که کسی می‌خواهد به یک دستیار برنامه‌نویسی هوش مصنوعی مانند Claude Code یا Cursor مرورگر بدهد. MCP (Model Context Protocol) راه استاندارد این دستیارها برای فراخوانی ابزارهای بیرونی است و هر دو کتابخانه سروری دارند که بر آن ساخته شده است.

Playwright MCP سرور Microsoft است. صفحه را به جای تصویر صفحه به شکل متن درخت دسترس‌پذیری به مدل می‌دهد، با `npx @playwright/mcp@latest` آغاز می‌شود و پرچم‌های `--proxy-server` و `--proxy-bypass` را می‌پذیرد. README آن یادآوری می‌کند که برای عامل‌های برنامه‌نویسی، راه خط فرمان توکن کمتری مصرف می‌کند، چون شِمای بزرگ ابزارها را در پنجره زمینه مدل بار نمی‌کند. نصب و اطلاعات ورود پروکسی در نوشته [Playwright MCP چیست؟](/fa/blog/playwright-mcp) آمده است.

[Chrome DevTools MCP](https://github.com/ChromeDevTools/chrome-devtools-mcp) به یک عامل برنامه‌نویسی امکان می‌دهد یک Chrome زنده را کنترل و بررسی کند؛ برای کنش‌ها از Puppeteer و برای ردگیری کارایی از DevTools استفاده می‌کند و با `npx -y chrome-devtools-mcp@latest` آغاز می‌شود. در نسخه 1.10.1، مقدار `--proxyServer` به شکل `--proxy-server` به Chrome داده می‌شود و فیلدی برای اطلاعات ورود ندارد، پس لیست سفید IP راه عملی است. به طور پیش‌فرض Chrome پایدار نصب‌شده را اجرا می‌کند و آمار استفاده را برای Google می‌فرستد، مگر آنکه `--no-usage-statistics` را بیفزایید.

برای عاملی که در صفحه‌ها کلیک می‌کند و فرم پر می‌کند Playwright MCP را به کار ببرید؛ برای عاملی که خطاهای کنسول، درخواست‌های شبکه و ردگیری کارایی سایت خودتان را می‌خواند، Chrome DevTools MCP را. در هر دو حالت جاهایی را که عامل می‌تواند برود محدود کنید (`--allowed-origins` یا `--allowedUrlPattern`)، رمزها را بیرون از پرامپت نگه دارید و کنش‌هایی را که چیزی را تغییر می‌دهند خودتان تأیید کنید.

## اجراگر آزمون، تولید کد و ردگیری

برتری Playwright در اینجا از همه جا بیشتر است. Playwright Test اجراگر، وارسی‌ها، اجرای موازی، تکرار آزمون‌های ناموفق و گزارش HTML را با خود می‌آورد؛ در Python افزونه pytest و در Java و .NET چارچوب‌های آزمون معمول همان زبان‌ها به کار می‌روند. فرمان `npx playwright codegen <url>` هم‌زمان با کلیک‌های شما کد می‌نویسد. Trace Viewer (`npx playwright show-trace trace.zip`) یک اجرای ضبط‌شده را با عکس‌های لحظه‌ای DOM، درخواست‌های شبکه و پیام‌های کنسول روی یک خط زمان بازپخش می‌کند تا ببینید چرا کار شبانه خالی برگشت.

Puppeteer آزمون را به خودتان وامی‌گذارد: آن را با Jest، Mocha یا اجراگر آزمون Node.js ترکیب کنید. برای ضبط، پنل **Recorder** (ضبط‌کننده) در Chrome DevTools یک نشست را به شکل اسکریپت Puppeteer، اسکریپت Puppeteer برای Firefox یا اسکریپتی همراه با تحلیل Lighthouse خروجی می‌گیرد. فراخوانی `page.tracing.start()` یک ردگیری کارایی Chrome برای DevTools می‌نویسد که نشان می‌دهد چرا صفحه کند است، اما بازپخش گام‌به‌گام اسکریپت شما نیست.

## سرعت: چرا رقم نمی‌دهیم

رقم‌های منتشرشده از جنس «X درصد سریع‌تر» روی دستگاه و صفحه کس دیگری اندازه گرفته شده‌اند. در Chromium هر دو ابزار با CDP گفت‌وگو می‌کنند و در پویشی که از پروکسی می‌گذرد بیشتر زمان صرف شبکه و سایت هدف می‌شود. انتخاب‌های راه‌اندازی، مانند Chrome کامل در برابر headless shell، از خود کتابخانه مهم‌ترند. اگر به رقم نیاز دارید، آن را روی هدف خودتان و با همان پروکسی و همان همروندی اندازه بگیرید.

## کاربردها

- **PDF و تصویر صفحه از یک سرویس Node.js:** هر دو `page.pdf()` دارند و هر دو در آزمون ما از Chromium فایل PDF ساختند؛ Puppeteer وابستگی سبک‌تری است.
- **آزمون سرتاسری روی چند موتور:** Playwright Test یک آزمون را در Chromium، Firefox و WebKit اجرا می‌کند.
- **جمع‌آوری داده با Python، Java یا .NET:** Playwright، چون Puppeteer تنها برای JavaScript است.
- **خودکارسازی نسخه پایدار Firefox:** Puppeteer از راه WebDriver BiDi.

هر ابزاری که برگزینید، قواعد `robots.txt` و شرایط استفاده سایت را رعایت کنید، اگر API رسمی وجود دارد از آن استفاده کنید و نرخ درخواست‌هایتان را در حدی نگه دارید که سایت بتواند از پس آن برآید.

## اشتباهات رایج

- **باز کردن یک context در Puppeteer بدون `page.authenticate()`.** Chrome اطلاعات ورود را برای هر context جداگانه نگه می‌دارد؛ context‌ای که هیچ صفحه‌ای در آن این فراخوانی را انجام نداده باشد با `net::ERR_INVALID_AUTH_CREDENTIALS` شکست می‌خورد.
- **انتظار اینکه Playwright وقتی پروکسی اطلاعات ورود می‌خواهد خطا پرتاب کند.** در آزمون ما پاسخی با وضعیت 407 برگرداند؛ `response.status()` را بررسی کنید.
- **نوشتن `user:pass@` در نشانی پروکسی.** Chrome اطلاعات ورود را از نشانی نمی‌گیرد؛ آن‌ها را در Puppeteer با `page.authenticate()` و در Playwright با فیلدهای `username` و `password` بدهید.
- **استفاده از SOCKS5 با رمز عبور در Chromium.** Chrome احراز هویت SOCKS5 ندارد؛ از لیست سفید IP استفاده کنید.
- **آزمودن پروکسی روی `localhost` در Puppeteer.** Chrome برای نشانی‌های loopback از پروکسی استفاده نمی‌کند، مگر آنکه `<-loopback>` را بیفزایید.
- **انتظار اینکه Firefox در Playwright همان Firefox نصب‌شده باشد.** ساختی وصله‌خورده است و WebKit هم Safari نیست.

## راهنمای انتخاب

| نیاز | پیشنهاد |
|---|---|
| اسکریپت Node.js که تنها به Chrome نیاز دارد | هر دو؛ Puppeteer کافی است |
| Python، Java یا .NET | Playwright |
| آزمون در موتور WebKit | Playwright |
| خودکارسازی نسخه پایدار Firefox | Puppeteer |
| اطلاعات ورود پروکسی که یک بار برای هر context تنظیم شود | Playwright |
| IP جداگانه برای هر نشست در یک مرورگر | هر دو، یک context برای هر نشست |
| مجموعه آزمون با وارسی و گزارش | Playwright Test |
| عاملی که فرم پر می‌کند | Playwright MCP |
| عاملی که کارایی را در Chrome اشکال‌زدایی می‌کند | Chrome DevTools MCP |

## پرسش‌های متداول

### آیا Playwright از Puppeteer بهتر است؟

نه در همه جهات. Playwright موتورها، زبان‌ها و ابزارهای آزمون بیشتری را پوشش می‌دهد؛ Puppeteer کوچک‌تر است و با نسخه پایدار Firefox کار می‌کند. اگر یک اسکریپت Puppeteer کارآمد نیاز شما را برآورده می‌کند، دلیلی برای بازنویسی آن نیست.

### آیا می‌توانم Puppeteer را با Python به کار ببرم؟

به طور رسمی نه. تنها کتابخانه رسمی Puppeteer برای JavaScript و TypeScript روی Node.js است؛ نسخه‌های بازنویسی‌شده برای Python وجود دارند، اما پروژه‌هایی شخص ثالث و بیرون از مخزن Puppeteer هستند. برای یک زنجیره پردازش با Python، Playwright کتابخانه‌ای رسمی دارد که همان قابلیت‌های خودکارسازی مرورگر نسخه Node.js را در اختیار می‌گذارد.

### آیا Puppeteer با Firefox کار می‌کند؟

بله. از نسخه 23 با نسخه پایدار Firefox از راه WebDriver BiDi کار می‌کند؛ آن را با `browser: "firefox"` اجرا می‌کنید. Firefox همراه بسته دانلود نمی‌شود مگر آنکه آن را در پیکربندی دانلود فعال کنید، و چند قابلیت که تنها در CDP هستند از راه BiDi در دسترس نیستند.

### آیا کوچ از Puppeteer به Playwright دشوار است؟

یک اسکریپت کوچک زود منتقل می‌شود، چون بسیاری از فراخوانی‌ها نام مشترک دارند: `goto`، `click`، `evaluate` و `pdf`. کار در سه جاست: اطلاعات ورود پروکسی به شیء `proxy` می‌رود، جفت‌های `waitForNavigation()` جای خود را به `waitForURL()` و locator‌ها می‌دهند، و browser context‌ها واحد جداسازی می‌شوند.

### با Claude Code یا یک عامل هوش مصنوعی دیگر کدام را به کار ببرم؟

به کار بستگی دارد. Playwright MCP برای راندن صفحه‌ها از راه درخت دسترس‌پذیری ساخته شده است؛ Chrome DevTools MCP که بر Puppeteer ساخته شده، در بررسی پیام‌های کنسول، درخواست‌های شبکه و ردگیری کارایی قوی‌تر است. می‌توانید هر دو را نصب کنید و به هر کار تنها سروری را بدهید که لازم دارد.

### آیا هیچ‌کدام از این دو ابزار می‌تواند از پروکسی SOCKS5 با نام کاربری و رمز عبور استفاده کند؟

در Chromium نه، چون Chrome هیچ احراز هویتی را برای SOCKS5 پشتیبانی نمی‌کند. SOCKS5 را با لیست سفید IP به کار ببرید، یا یک پروکسی HTTP با نام کاربری و رمز عبور. سازنده نقطه اتصال در پنل ما پورت SOCKS5 هر محصول را نشان می‌دهد.

## خلاصه

Puppeteer و Playwright یک Chromium را به شیوه‌ای تقریباً یکسان اداره می‌کنند؛ تفاوت در چیزهایی است که پیرامون آن قرار دارد. Puppeteer کتابخانه‌ای Node.js برای Chrome و نسخه پایدار Firefox است و اطلاعات ورود پروکسی را با `page.authenticate()` می‌گیرد و برای هر browser context نگه می‌دارد. Playwright موتور WebKit، سه زبان رسمی دیگر، اجراگر آزمون همراه با ردگیری و گزینه `proxy` را می‌افزاید که اطلاعات ورود را برای هر context با خود دارد. برای کار Node.js که تنها به Chrome نیاز دارد Puppeteer کافی است؛ برای چند زبان، چند موتور یا یک مجموعه آزمون، Playwright مناسب‌تر است. گونه‌های پروکسی که با هر دو ابزار کار می‌کنند در [خدمات پروکسی ما](/fa/proxy) آمده‌اند.
