خانه/مقالات/اسکریپ Playwright: مدیریت User-Agentها
استخراج داده
Playwright
برگشت به صفحه مقاله ها
اسکریپ Playwright: مدیریت User-Agentها

اسکریپ Playwright: مدیریت User-Agentها

این مقاله روش‌های عملی مدیریت User-Agent در وب اسکریپینگ با Playwright را توضیح می‌دهد؛ از تنظیم مستقیم و چرخاندن UA تا استفاده از پلاگین‌های stealth و APIهای بیرونی. با مثال‌های پایتون و Node.js، نکات عیب‌یابی، امنیتی و بهترین‌روش‌ها را برای اجرای پایدار و کم‌ریسک اسکریپ‌ها پوشش می‌دهد.
امیر حسین حسینیان
امیر حسین حسینیان
1404-11-21

مقدمه

در این مقاله به‌طور عملی یاد می‌گیریم چطور در پروژه‌های وب اسکریپینگ با Playwright کنترل User-Agent را به دست بگیریم. هدف این راهنما این است که بفهمی چرا تغییر یا چرخاندن User-Agent مهم است، چه روش‌هایی برای انجام آن وجود دارد، و چگونه با مثال‌های کد هم در Python و هم در Node.js این کار را انجام دهی. در پایان می‌توانی User-Agent را امن و مؤثر مدیریت کنی، خطاهای معمول را رفع کنی و از ابزارهای اتوماتیک برای دریافت رشته‌های معتبر استفاده کنی.

تنظیم مستقیم User-Agent در Playwright (پایتون)

ایده ساده است: هنگام ساختن context در Playwright، فیلد user_agent را تعیین کن تا همه درخواست‌ها با آن رشته ارسال شوند. مناسب برای مواردی که می‌خواهی سریع یک UA ثابت استفاده کنی.

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch()
    # ورودی: رشته User-Agent دلخواه
    context = browser.new_context(user_agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/78.0.3904.108 Safari/537.36")
    page = context.new_page()
    # خروجی: مقدار واقعی navigator.userAgent در صفحه
    ua = page.evaluate("() => navigator.userAgent")
    print("User-Agent:", ua)
    browser.close()

توضیح خط‌به‌خط:

  • ورودی: تو یک رشته User-Agent به new_context می‌دهی.
  • عملیات: Playwright تمام درخواست‌های آن context را با هدر User-Agent مشخص‌شده ارسال می‌کند.
  • خروجی: با page.evaluate می‌توانی بررسی کنی که navigator.userAgent در محیط مرورگر چه مقداری دارد.

نکته: این روش ساده است اما اگر فقط UA را تغییر دهی و بقیه امضای مرورگر (مثل navigator.webdriver یا قابلیت‌های WebRTC) دست‌نخورده بماند، سایت‌های پیشرفته همچنان می‌توانند رفتار اتوماتیک را تشخیص دهند.

تنظیم مستقیم در Node.js (مثال)

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();
  const context = await browser.newContext({
    userAgent: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/78.0.3904.108 Safari/537.36"
  });
  const page = await context.newPage();
  const ua = await page.evaluate(() => navigator.userAgent);
  console.log('User-Agent:', ua);
  await browser.close();
})();

همان توضیحات نسخه پایتون برای این نسخه Node.js نیز صادق است. این مثال نشان می‌دهد چگونه یک UA ثابت تنظیم می‌شود و چگونه مقدار واقعی در صفحه خوانده می‌شود.

چرخاندن یا انتخاب تصادفی User-Agent برای هر جلسه

مزیت: با تغییر User-Agent برای هر session احتمال بلاک شدن کمتر می‌شود. دو رویکرد رایج وجود دارد:

  1. استفاده از یک مجموعه محلی از رشته‌های معتبر و انتخاب تصادفی
  2. درخواست به یک سرویس یا API که User-Agent معتبر و به‌روز فراهم می‌کند

مثال Python: گرفتن یک User-Agent از API (نمونه با requests) و اعمال آن در context:

import requests
from playwright.sync_api import sync_playwright

# ورودی: کلید API یا نقطهٔ انتهایی که یک لیست User-Agent برمی‌گرداند
def fetch_user_agent(api_key: str):
    # اینجا فقط الگو نشان داده شده؛ پاسخ باید شکل JSON با یک رشته یا آرایه داشته باشد
    resp = requests.get(f"https://api.fake-ua.example/get?api_key={api_key}")
    resp.raise_for_status()
    data = resp.json()
    # خروجی: یک رشته User-Agent
    return data["results"][0]

with sync_playwright() as p:
    ua = fetch_user_agent("YOUR_API_KEY")
    browser = p.chromium.launch()
    context = browser.new_context(user_agent=ua)
    page = context.new_page()
    print(page.evaluate("() => navigator.userAgent"))
    browser.close()

توضیح: تابع fetch_user_agent یک درخواست HTTP به سرویس خارجی می‌زند و یک User-Agent معتبر برمی‌گرداند. سپس آن رشته به new_context داده می‌شود.

نکتهٔ عملی: اگر از سرویس خارجی استفاده می‌کنی، باید خطاها (rate limit، عدم پاسخ) را هندل کنی و یک fallback محلی داشته باشی.

نمونهٔ Node.js با بسته random-useragent

const { chromium } = require('playwright');
const randomUserAgent = require('random-useragent');

(async () => {
  const browser = await chromium.launch({ headless: true });
  const context = await browser.newContext({
    userAgent: randomUserAgent.getRandom()
  });
  const page = await context.newPage();
  const ua = await page.evaluate(() => navigator.userAgent);
  console.log('User-Agent:', ua);
  await browser.close();
})();

مزایا: بسته‌های محلی مثل random-useragent مدیریت مجموعه UA را ساده می‌کنند؛ معایب: ممکن است داده‌ها قدیمی یا نامتناسب با قابلیت‌های مرورگر باشند که باعث ناسازگاری شود.

استفاده از پلاگین Stealth و ترفندهای اضافی

پلاگین‌های stealth مجموعه‌ای از هک‌های کوچک را انجام می‌دهند تا امضای سرور-پذیری (browser fingerprint) به‌صورت انسانی‌تر دیده شود. در اکوسیستم Node، ترکیب playwright-extra و پلاگین‌های stealth رایج است.

const { chromium } = require('playwright-extra');
const stealth = require('puppeteer-extra-plugin-stealth')();
chromium.use(stealth);

(async () => {
  const browser = await chromium.launch();
  const context = await browser.newContext();
  const page = await context.newPage();
  await page.goto('about:blank');
  // پلاگین stealth زیرساخت‌ها مثل navigator.webdriver را مدیریت می‌کند
  await browser.close();
})();

در پایتون معادل مستقیم کامل ممکن است موجود نباشد، بنابراین معمولاً ترکیبی از تغییرات دستی و تنظیم headers انجام می‌شود:

# تکنیک‌های دستی برای کاهش اثر headless
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    context = browser.new_context()
    page = context.new_page()
    # اجرای جاوااسکریپت قبل از لود صفحه برای تغییر چند مشخصه
    page.add_init_script("""
    Object.defineProperty(navigator, 'webdriver', {get: () => undefined});
    Object.defineProperty(navigator, 'languages', {get: () => ['en-US', 'en']});
    Object.defineProperty(navigator, 'platform', {get: () => 'Win32'});
    """)
    page.goto('https://example.com')
    browser.close()

توضیح: add_init_script اسکریپتی را قبل از اجرای هر کدی روی صفحه تزریق می‌کند تا برخی پرچم‌های شناخته‌شدهٔ headless اصلاح شوند. این روش به‌تنهایی کافی نیست ولی در ترکیب با UA مناسب و تغییر سایر هدرها مؤثر خواهد بود.

دریافت و مدیریت مجموعه User-Agentها

چند منبع شناخته‌شده عبارت‌اند از useragentstring.com و whatismybrowser.com که می‌توانی رشته‌ها را از آن‌ها استخراج یا بررسی کنی. همچنین سرویس‌های API (مثل نمونهٔ ScrapeOps Fake User-Agent API) وجود دارند که به‌صورت JSON لیست UA فراهم می‌کنند.

// نمونهٔ Node.js با axios (الگو):
const axios = require('axios');

async function getUserAgents(apiKey) {
  const resp = await axios.get(`https://headers.example.io/v1/user-agents?api_key=${apiKey}`);
  return resp.data.results; // خروجی: آرایه‌ای از رشته‌های UA
}

getUserAgents('YOUR_API_KEY').then(list => console.log(list));
# نمونهٔ Python با requests
import requests

def get_user_agents(api_key: str):
    resp = requests.get(f"https://headers.example.io/v1/user-agents?api_key={api_key}")
    resp.raise_for_status()
    return resp.json().get('results', [])

print(get_user_agents('YOUR_API_KEY'))

نکتهٔ عملی: همیشه داده‌های دریافتی از API را پالایش (sanitize) کن تا رشته‌های ناصحیح یا خیلی قدیمی وارد چرخهٔ اسکریپت نشوند.

راهنمای عیب‌یابی (Troubleshooting)

  • شفاف بودن headless: اگر navigator.userAgent شامل "Headless" است، برخی سایت‌ها بلاک می‌کنند — از تنظیم دستی UA و ترفندهای stealth استفاده کن.
  • ناسازگاری UA و قابلیت‌ها: اگر UA جدید بیانگر نسخه‌ای از مرورگر است که امکاناتش با آنچه مرورگر واقعی ارائه می‌دهد همخوانی ندارد، سایت مشکوک می‌شود. راه‌حل: انتخاب UAهایی که با نسخه مرورگر در runtime تطابق دارند.
  • تکیه‌بر UA تنها کافی نیست: سایر امضاها مثل هدرهای شبکه، fingerprint جاوااسکریپت، رفتار موس/کیبورد، و زمان‌بندی درخواست‌ها را هم مدیریت کن.
  • یکپارچگی session: هنگام استفاده از چندین instance مطمئن شو که هدرها، کوکی‌ها و توکن‌ها بین درخواست‌های مرتبط سازگار هستند.
  • مشکلات با افزونه‌ها: تغییر UA ممکن است روی افزونه‌ها یا اسکریپت‌هایی که به UA وابسته‌اند تأثیر بگذارد؛ در محیط تست آنها را بازبینی کن.
  • لاگ‌گیری و تست گسترده: برای هر تغییر UA، خروجی navigator و رفتار صفحه را ثبت کن تا در صورت بروز خطا راحت‌تر ریشه‌یابی شود.

نکات امنیتی و بهترین روش‌ها

  • از چرخش منطقی UA استفاده کن نه تغییر دائمی و عجیب؛ مدل «سازگاری انسانی» را حفظ کن.
  • همیشه به قوانین سایت‌ها و قوانین محلی احترام بگذار؛ scraping بدون مجوز می‌تواند پیامد حقوقی داشته باشد.
  • در کنار UA، هدرهای دیگری مثل Accept-Language و Referer را هم منطقی تنظیم کن تا با UA سازگاری داشته باشند.
  • زمان‌بندی و نرخ درخواست‌ها (rate limiting) را شبیه رفتار انسانی نگه دار تا سرورها را تحت فشار قرار ندهی.
  • در صورت نیاز از پراکسی‌های باکیفیت استفاده کن تا IP-based blocking کاهش یابد.

جمع‌بندی

کنترل User-Agent یکی از ابزارهای مهم در وب اسکریپینگ با Playwright است، اما به‌تنهایی کافی نیست. ترکیب تنظیم دقیق UA، چرخش منطقی، اصلاح سایر امضاهای مرورگر و تست مداوم بهترین نتیجه را می‌دهد. از سرویس‌ها یا کتابخانه‌های معتبر برای مدیریت UA استفاده کن و همیشه موارد امنیتی و سازگاری را در نظر بگیر.

مقاله‌های مرتبط