مقدمه
در این مقاله مرحلهبهمرحله روشهای متداول برای اسکریپ کردن ورود (login) به وبسایتها با استفاده از Node.js و Playwright را بررسی میکنیم. هدف این راهنما ارائهٔ راهحلهای عملی برای: ورود ساده، ورود چندمرحلهای، مقابله با مکانیزمهای ضدربات، حل CAPTCHA، و حفظ دسترسی بلندمدت بدون بلاک شدن است. در پایان مقاله شما نمونهکدهای آماده خواهید داشت و میدانید هر قطعه کد چه ورودی و خروجیای دارد و چگونه آن را امن و پایدار کنید.
ورود ساده با Playwright
ایده کلی: وقتی صفحهٔ لاگین فیلدهای username و password را همزمان نمایش میدهد، میتوانیم با انتخابگرهای CSS ساده و توابع همگام Playwright فرم را تکمیل و ارسال کنیم.
نکات مهم قبل از اجرا:
- از متغیرهای محیطی برای نگهداری رمز و نام کاربری استفاده کنید (مثلا process.env.USERNAME)، هرگز اطلاعات حساس را هاردکد نکنید.
- همیشه قبل از type یا click روی المنتها با waitForSelector یا گزینههای visible صبر کنید تا المان در DOM قابل تعامل باشد.
مثال ساده (توضیح: این تابع یک صفحه باز میکند، به آدرس میرود، فیلدها را پر میکند و دکمه ارسال را کلیک میکند):
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 و تاخیر شبیهسازی کاربر انجام میشود. خروجی تابع: صفحه در حالت لاگین شده آمادهٔ اسکریپ کردن است.
ورود چندمرحلهای (Multi-Stage)
ایده کلی: بسیاری از سایتها فرم مرحلهای دارند (ابتدا ایمیل، سپس گذرواژه). در این حالت باید بین صفحات یا بخشها حرکت کنید و برای هر مرحله انتظار صریح بگذارید.
نکات کلیدی:
- از waitForNavigation یا waitForSelector با گزینهٔ visible:true استفاده کنید تا صفحه یا المان جدید آماده شود.
- اگر کلیک دکمه باعث نافشانی AJAX میشود، از Promise.all([page.waitForNavigation(), page.click(...)]) بهره ببرید تا رقابت بین رویدادها مدیریت شود.
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 صفحات بعدی را اسکریپ کرد.
دورزدن تشخیص ضدربات (Stealth)
چالش: 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ها
مسئله: CAPTCHAها برای جلوگیری از اتوماسیون طراحی شدهاند. یکی از رویکردهای رایج، استفاده از سرویسهای حل خودکار مثل 2Captcha و پلاگینهای puppeteer-extra-plugin-recaptcha است.
نکات عملی:
- برای استفاده از سرویسهای تجاری نیاز به کلید API و اعتبار (balance) دارید.
- همیشه خروجی و وضعیت حل را مدیریت کنید (موفق/ناموفق) و زمانهای طولانی پاسخ را با تایمآوت منطقی هندل کنید.
- استفاده از این سرویسها میتواند هزینهبر باشد و همچنین مسائل حقوقی و حریم خصوصی را در پی داشته باشد.
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 ارسال کند. خروجی نهایی زمانی است که فرم ارسال شده و صفحه وارد حالت بعدی (مثلاً داشبورد) برود.
بعد از ورود: جلوگیری از بلاک شدن
ورود موفق تنها آغاز است؛ نگهداری دسترسی و جلوگیری از شناسایی مهمتر است. نکات و بهترین روشها:
- چرخش حسابها: استفاده از چند حساب برای توزیع درخواستها و جلوگیری از تمرکز ترافیک روی یک شناسه کاربری.
- پروکسیها: استفاده از پروکسیهای مسکونی (residential) به جای دیتاسنتری در سایتهای با محافظت بالا؛ در صورت نیاز از IPهای استاتیک/ثابت برای کاهش هشدارهای تغییر IP استفاده کنید.
- الگوهای واقعی درخواست: شبیهسازی رفتار انسانی: تاخیر بین کلیکها، پیمایش صفحه، لود تصاویر و تعامل با المانها.
- مدیریت کوکی و سشن: ذخیره و بازیابی کوکیها/localStorage تا لازم نباشد هر بار مجدداً لاگین کنید.
- محدودیت نرخ (Rate limiting): محدود کردن تعداد درخواستها در دقیقه و افزودن jitter به فواصل برای جلوگیری از الگوهای منظم.
- نظارت و retries: لاگ برداری از خطاها، retry با backoff و آگاهسازی در صورت بلاک شدن یا خطاهای عجیب.
ریسکها و پیامدهای قانونی
اسکریپ کردن پشت لاگین ریسکهای بیشتری نسبت به اسکریپ صفحات عمومی دارد:
- اطلاعات شخصی: استفاده از حسابهای واقعی میتواند شما را به دادههای شناساییشدنی مرتبط کند؛ امنیت اطلاعات حساب را جدی بگیرید.
- بسته شدن حساب: سایتها میتوانند حسابها را معلق یا حذف کنند؛ همیشه آمادهٔ جایگزینی حسابها و پشتیبانگیری باشید.
- مسائل حقوقی: قوانین سرویس و قوانین محلی را بررسی کنید—در برخی موارد اسکریپ کردن پشت لاگین میتواند پیامد قضایی داشته باشد.
جمعبندی و توصیههای نهایی
خلاصهٔ عملی:
- برای اسکریپ کردن ورود از انتخابگرهای صریح و waitهای مناسب استفاده کنید.
- ورودهای چندمرحلهای را با ترتیب دقیق و مدیریت navigation پیادهسازی کنید.
- برای کاهش شناسایی از پلاگینهای stealth، تغییر user-agent، و تعاملات انسانینما بهره ببرید، ولی قوانین سایت را رعایت کنید.
- حل CAPTCHA معمولاً با سرویسهای پولی انجام میشود و نیاز به مدیریت هزینه و خطا دارد.
- برای جلوگیری از بلاک شدن، از پروکسی مناسب، چرخش حساب و الگوهای رفتاری واقعی استفاده کنید و کوکی/سشن را نگهداری کنید.
اگر دنبال پیادهسازی پایدار هستید: ساختن pipeline با لاگ، مانیتورینگ، و تست مداوم باعث میشود اسکریپر شما قابلاطمینانتر و طولانیمدت قابل استفاده باشد.





