خانه/مقالات/اسکریپینگ با User-Agentهای تقلبی در Python
پروکسی و چرخش IP
ضد بلاک (Anti-bot)
مدیریت سشن و کوکی
برگشت به مقاله‌ها

اسکریپینگ با User-Agentهای تقلبی در Python

اسکریپینگ با User-Agentهای تقلبی در Python
این مقاله روش‌های عملی برای تنظیم و چرخاندن User-Agent و هدرهای مرورگر در اسکریپینگ با Python و hrequests را توضیح می‌دهد؛ از تنظیم هدر ساده تا ادغام با APIهای آماده، مدیریت سشن، نکات امنیتی و بهترین‌روش‌ها برای کاهش احتمال بلاک شدن را پوشش می‌دهد.
آسان اسکریپ آسان اسکریپ
1405-05-04

مقدمه

در این مقاله یک راهنمای عملی و تکنیکی برای استفاده از User-Agentهای تقلبی در اسکریپینگ با Python و کتابخانه hrequests ارائه می‌کنیم. بعد از خواندن این مطلب شما یاد می‌گیرید چگونه:

  • User-Agent استاندارد را در درخواست تنظیم کنید
  • User-Agent را در سشن‌ها (Session) مدیریت کنید
  • چگونه User-Agentها را بچرخانید (rotate) و از لیست بزرگ استفاده کنید
  • چگونه با APIهای آماده مثل ScrapeOps فهرست User-Agent یا هدرهای کامل مرورگر بگیرید
  • نکات امنیتی، عملکردی و بهترین روش‌ها برای کاهش ریسک بلاک شدن

User-Agent چیست و چرا اهمیت دارد

User-Agent یک رشته متنی است که مرورگر یا کلاینت HTTP به سرور می‌فرستد و اطلاعاتی مثل نوع مرورگر، سیستم‌عامل و نسخه‌ها را مشخص می‌کند. سرورها از این رشته برای شخصی‌سازی پاسخ و همچنین تشخیص ترافیک غیرانسانی استفاده می‌کنند.

مثال یک User-Agent رایج:

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36'

اگر از تنظیمات پیش‌فرضِ کتابخانه‌هایی مثل hrequests استفاده کنید، رشته‌ای مشابه 'python-hrequests/2.26.0' ارسال می‌شود که به‌راحتی نشان می‌دهد درخواست از یک اسکریپر می‌آید و احتمالاً بلاک خواهید شد.

تنظیم User-Agent در درخواست‌های hRequests

برای تغییر User-Agent کافی است یک دیکشنری headers بسازید و آن را به پارامتر headers در hrequests.get یا متدهای دیگر پاس دهید.

import hrequests

headers = {
    "User-Agent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148"
}

r = hrequests.get('http://httpbin.org/headers', headers=headers)
print(r.json())

توضیحات:

  • ورودی: یک رشته URL و دیکشنری headers.
  • خروجی: یک شیء پاسخ (r) که با r.json() می‌توان محتوای JSON آن را دید.
  • خط‌به‌خط: وارد کردن کتابخانه، تعریف هدر، ارسال درخواست با هدر سفارشی و چاپ پاسخ.

استفاده از Session برای هدرهای پیش‌فرض

وقتی چندین درخواست به یک دامنه می‌زنید بهتر است از سشن استفاده کنید تا هدرها و کوکی‌ها را برای تمام درخواست‌ها حفظ کنید.

import hrequests

headers = {
    "User-Agent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148"
}

s = hrequests.Session()
s.headers.update(headers)

r = s.get('http://httpbin.org/headers')
print(r.json())

توضیح: با این کار هر فراخوانی روی s.get به‌طور پیش‌فرض همین هدرها را خواهد داشت؛ مزیت: سازگاری هدرها و مدیریت کوکی‌ها، کاهش هزینه ایجاد چند اتصال جداگانه.

چرخاندن (Rotate) User-Agent

یک روش ساده برای کاهش شناسایی، چرخاندن User-Agent در هر درخواست است. این روش نیاز به فهرستی از User-Agentهای به‌روز دارد.

import hrequests
import random

user_agent_list = [
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36',
    'Mozilla/5.0 (iPhone; CPU iPhone OS 14_4_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Mobile/15E148 Safari/604.1',
    'Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)',
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36'
]

headers = {"User-Agent": random.choice(user_agent_list)}
r = hrequests.get('http://httpbin.org/headers', headers=headers)
print(r.json())

نکات و محدودیت‌ها:

  • مزیت: ساده و سریع؛ جلوی بلاک‌های ساده را می‌گیرد.
  • معایب: نگهداری لیست به‌روز وقت‌گیر است؛ اگر فقط User-Agent را تغییر دهید ولی بقیه هدرها ثابت باشند، تشخیص همچنان ممکن است.

ادغام با API برای مدیریت هزاران User-Agent

راه مقیاس‌پذیرتر استفاده از یک سرویس/API است که فهرست User-Agentها را به‌روز نگه دارد—مثلاً سرویس ScrapeOps. در ادامه نمونه‌ی ادغام با چنین API‌ای را می‌بینید که نکات مربوط به خطا و timeout را هم درنظر گرفته‌ام.

import hrequests
import time
import random

SCRAPEOPS_API_KEY = 'YOUR_API_KEY'

def get_user_agent_list(api_key, retries=3, backoff=1.0):
    url = 'https://headers.scrapeops.io/v1/user-agents?api_key=' + api_key
    for attempt in range(retries):
        try:
            r = hrequests.get(url, timeout=10)
            if r.status_code == 200:
                data = r.json()
                return data.get('result', [])
            else:
                time.sleep(backoff * (attempt + 1))
        except Exception:
            time.sleep(backoff * (attempt + 1))
    return []

def get_random_user_agent(user_agent_list):
    if not user_agent_list:
        return 'Mozilla/5.0'
    return random.choice(user_agent_list)

# استفاده در اسکریپر
user_agent_list = get_user_agent_list(SCRAPEOPS_API_KEY)
urls = ['https://example.com/1', 'https://example.com/2']
for url in urls:
    headers = {'User-Agent': get_random_user_agent(user_agent_list)}
    r = hrequests.get(url, headers=headers, timeout=15)
    print(r.status_code)

توضیحات:

  • get_user_agent_list: ورودی: کلید API، خروجی: لیستی از User-Agentها؛ دارای retry و backoff برای افزایش پایداری.
  • get_random_user_agent: ورودی: لیست، خروجی: یک رشته User-Agent؛ در صورت خالی بودن لیست، یک مقدار پیش‌فرض برمی‌گرداند.
  • در حلقه اصلی برای هر URL یک User-Agent تصادفی انتخاب می‌شود و در هدر request قرار می‌گیرد.

هدرهای کامل مرورگر (Fake Browser Headers)

برای سایت‌های پیچیده‌تر فقط تغییر User-Agent کافی نیست؛ باید مجموعه‌ای از هدرهایی که مرورگر واقعی ارسال می‌کند را تقلید کنید تا شناسایی سخت‌تر شود.

browser_headers_example = {
    'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="99", "Google Chrome";v="99"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"macOS"',
    'Upgrade-Insecure-Requests': '1',
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.83 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
    'Sec-Fetch-Site': 'none',
    'Sec-Fetch-Mode': 'navigate',
    'Sec-Fetch-User': '?1',
    'Sec-Fetch-Dest': 'document',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'en-GB,en-US;q=0.9,en;q=0.8'
}

r = hrequests.get('https://example.com', headers=browser_headers_example)
print(r.status_code)

نکته: اگر از API هدر استفاده می‌کنید، آن API معمولاً مجموعه‌ای از هدرها را به‌صورت یک آبجکت JSON برمی‌گرداند که می‌توانید مستقیم در hrequests.get استفاده کنید.

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

  • استفاده از پراکسی: چرخاندن IP با پراکسی‌ها به‌خصوص در کنار چرخاندن User-Agent بسیار مهم است.
  • زمان‌بندی و نرخ درخواست: از تاخیر تصادفی بین درخواست‌ها استفاده کنید و سقف نرخ (rate limit) را رعایت کنید تا رفتار انسانی تقلید شود.
  • مدیریت خطا: timeout، retry با backoff نمایی و لاگ کردن وضعیت‌های خطا را پیاده‌سازی کنید.
  • سشن‌ها و کوکی‌ها: از Session برای نگهداری کوکی‌ها و کاهش overhead اتصال استفاده کنید.
  • سازگاری هدرها: بهتر است مجموعه‌ای از هدرها را (نه فقط User-Agent) به‌صورت سازگار ارسال کنید تا تفاوت‌های منطقی بین درخواست‌ها کاهش یابد.
  • امنیت: از TLS معتبر استفاده کنید، هدرهای حساس مانند Authorization را امن نگه دارید و کلیدهای API را در متغیر محیطی یا vault ذخیره کنید.
  • پایداری: کش محلی (short-term) برای صفحات غیرمتحرک می‌تواند تعداد درخواست‌ها را کاهش دهد.
  • اخلاق و قانون: حریم خصوصی، شرایط استفاده و قوانین سایت‌ها را بررسی کنید؛ از بارگذاری بیش از حد روی سرورها خودداری کنید.

جمع‌بندی

استفاده از User-Agentهای تقلبی فقط یک گام در مقابل شناسایی است؛ ترکیب آن با هدرهای کامل مرورگر، سشن‌های هوشمند، استفاده از پراکسی و مکانیزم‌های retry/backoff بهترین نتیجه را می‌دهد. با رعایت نکات عملکردی و اخلاقی، می‌توانید پایداری اسکریپرها را به‌طور چشمگیری افزایش دهید.

مطالب مرتبط

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