

در این مقاله مرحلهبهمرحله روشهای متداول برای اسکریپ کردن ورود (login) به وبسایتها با استفاده از Node.js و Playwright را بررسی میکنیم. هدف این راهنما ارائهٔ راهحلهای عملی برای: ورود ساده، ورود چندمرحلهای، مقابله با مکانیزمهای ضدربات، حل CAPTCHA، و حفظ دسترسی بلندمدت بدون بلاک شدن است. در پایان مقاله شما نمونهکدهای آماده خواهید داشت و میدانید هر قطعه کد چه ورودی و خروجیای دارد و چگونه آن را امن و پایدار کنید.
ایده کلی: وقتی صفحهٔ لاگین فیلدهای username و password را همزمان نمایش میدهد، میتوانیم با انتخابگرهای CSS ساده و توابع همگام Playwright فرم را تکمیل و ارسال کنیم.
نکات مهم قبل از اجرا:
مثال ساده (توضیح: این تابع یک صفحه باز میکند، به آدرس میرود، فیلدها را پر میکند و دکمه ارسال را کلیک میکند):
import { chromium } from "playwright";
async function loginSimple() {
const browser = await chromium.launch({ headless: false });
const page = await browser.newPage();
// مسیر صفحهٔ لاگین
await page.goto("http://quotes.toscrape.com/");
// مطمئن میشویم لینک لاگین ظاهر شده
await page.waitForSelector('.col-md-4 a');
await page.click('.col-md-4 a');
// پر کردن فرم
await page.waitForSelector('#username');
await page.type('#username', process.env.USERNAME || 'Your_Username', { delay: 100 });
await page.waitForSelector('#password');
await page.type('#password', process.env.PASSWORD || 'Your_Password', { delay: 100 });
// ارسال فرم
await page.click('.btn.btn-primary');
// در صورت نیاز میتوانید کوکیها را ذخیره کنید یا صبر کنید تا صفحهٔ پروفایل لود شود
await page.waitForLoadState('networkidle');
// cleanup
// await browser.close();
}
loginSimple();شرح کوتاه خطبهخط: این تابع یک مرورگر کرومیم اجرا میکند، صفحه باز میشود، با waitForSelector منتظر المان میمانیم تا تداخلهای async حذف شوند، سپس با type و تاخیر شبیهسازی کاربر انجام میشود. خروجی تابع: صفحه در حالت لاگین شده آمادهٔ اسکریپ کردن است.
ایده کلی: بسیاری از سایتها فرم مرحلهای دارند (ابتدا ایمیل، سپس گذرواژه). در این حالت باید بین صفحات یا بخشها حرکت کنید و برای هر مرحله انتظار صریح بگذارید.
نکات کلیدی:
import { chromium } from "playwright";
async function loginMultiStage() {
const browser = await chromium.launch({ headless: false });
const page = await browser.newPage();
await page.goto('https://example-multi-stage.com/login');
// مرحلهٔ اول: ایمیل
await page.waitForSelector('input[name=email]');
await page.type('input[name=email]', process.env.EMAIL || 'you@example.com', { delay: 100 });
// کلیک ادامه و انتظار برای بارگذاری مرحلهٔ بعد
await Promise.all([
page.waitForNavigation({ waitUntil: 'networkidle' }),
page.click('input[id=continue]')
]);
// مرحلهٔ دوم: وارد کردن پسورد
await page.waitForSelector('input[name=password]');
await page.type('input[name=password]', process.env.PASSWORD || 'YourPassword', { delay: 100 });
await Promise.all([
page.waitForNavigation({ waitUntil: 'networkidle' }),
page.click('input[id=signInSubmit]')
]);
// اکنون لاگین انجام شده است
}
loginMultiStage();خروجی: پس از اجرای موفق، session و کوکیها در context جاری ذخیره میشوند و میتوان با همان context صفحات بعدی را اسکریپ کرد.
چالش: Playwright در حالت پیشفرض fingerprintهایی تولید میکند که بعضی سیستمهای ضدربات براساس آن متوجه ربات میشوند. راهکار: استفاده از پلاگینهای stealth که تعدادی از fingerprintها را اصلاح میکنند.
نکات امنیتی و اخلاقی: استفاده از پلاگینهای stealth ممکن است قوانین سایت را نقض کند؛ از نظر قانونی و اخلاقی قبل از اعمال این روش بررسی کنید.
// این مثال از playwright-extra و پلاگین stealth استفاده میکند
import { chromium } from "playwright-extra";
import StealthPlugin from "puppeteer-extra-plugin-stealth";
chromium.use(StealthPlugin());
(async () => {
const browser = await chromium.launch({ headless: false, args: ['--no-sandbox'] });
const context = await browser.newContext({
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.91 Safari/537.36'
});
const page = await context.newPage();
await page.goto('https://accounts.google.com', { waitUntil: 'networkidle' });
// ادامهٔ ورود مانند مثالهای قبل
})();توضیح: با فراخوانی chromium.use(StealthPlugin()) پلاگین تلاش میکند سرورها را فریب دهد و fingerprintهای شناختهشده را کاهش دهد. این روش به خودیِ خود تضمین عبور کامل از همهٔ سیستمها نیست؛ بسیاری از سایتها تحلیل رفتاری یا CAPTCHA هم دارند.
مسئله: CAPTCHAها برای جلوگیری از اتوماسیون طراحی شدهاند. یکی از رویکردهای رایج، استفاده از سرویسهای حل خودکار مثل 2Captcha و پلاگینهای puppeteer-extra-plugin-recaptcha است.
نکات عملی:
import { chromium } from 'playwright-extra';
import RecaptchaPlugin from 'puppeteer-extra-plugin-recaptcha';
chromium.use(RecaptchaPlugin({
provider: { id: '2captcha', token: process.env.TWO_CAPTCHA_KEY || 'YOUR_KEY' },
visualFeedback: true
}));
async function loginWithCaptcha() {
const browser = await chromium.launch({ headless: false });
const page = await browser.newPage();
await page.goto('https://app.scrapingbee.com/account/login');
await page.waitForSelector('#email');
await page.type('#email', process.env.EMAIL || 'you@example.com', { delay: 100 });
await page.waitForSelector('#password');
await page.type('#password', process.env.PASSWORD || 'YourPassword');
// فراخوانی پلاگین برای حل reCAPTCHA/hCaptcha در صفحه
await page.solveRecaptchas();
await Promise.all([
page.waitForNavigation(),
page.click('[type="submit"]')
]);
}
loginWithCaptcha();توضیح: solveRecaptchas() پلاگین را مجبور میکند CAPTCHAها را شناسایی و برای حل به سرویس 2Captcha ارسال کند. خروجی نهایی زمانی است که فرم ارسال شده و صفحه وارد حالت بعدی (مثلاً داشبورد) برود.
ورود موفق تنها آغاز است؛ نگهداری دسترسی و جلوگیری از شناسایی مهمتر است. نکات و بهترین روشها:
اسکریپ کردن پشت لاگین ریسکهای بیشتری نسبت به اسکریپ صفحات عمومی دارد:
خلاصهٔ عملی:
اگر دنبال پیادهسازی پایدار هستید: ساختن pipeline با لاگ، مانیتورینگ، و تست مداوم باعث میشود اسکریپر شما قابلاطمینانتر و طولانیمدت قابل استفاده باشد.


