مقدمه
در این مقاله یک راهنمای عملی و تکنیکی برای استفاده از 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 بهترین نتیجه را میدهد. با رعایت نکات عملکردی و اخلاقی، میتوانید پایداری اسکریپرها را بهطور چشمگیری افزایش دهید.





