مقدمه
در این مقاله بهصورت عملی و فنی یاد میگیریم چطور یک اسکریپر پایتون بسازیم که کمتر شناسایی و بلاک شود. هدف این راهنما این است که بفهمی چه هشدارهایی سایتها برای تشخیص ربات استفاده میکنند (مثلاً آیپی، TLS/TCP، هدرها، fingerprint مرورگر، کوکیها) و چگونه با تکنیکهای ساده و پیشرفته — از بهینهسازی هدر تا استفاده از پراکسی و رفع نشتیهای مرورگر — ریسک بلاک شدن را کاهش دهی. مخاطب این مطلب توسعهدهنده پایتون در سطح متوسط است که انتظار مثالهای کدنویسی و نکات عملی دارد.
هدرها: پایهی اول برای طبیعی نشاندادن درخواستها
هدرها یکی از اولین مکانهایی هستند که سایتها برای تشخیص ربات به آن نگاه میکنند. دو نکته کلیدی: محتوای هدرها (مقادیر مثل User-Agent) و ترتیب ارسال آنها. استفاده از هدرهای کتابخانهها (مثلاً هدرهای پیشفرض requests) معمولاً شما را لو میدهد.
نمونهی هدر واقعی که مرورگر کروم روی macOS ارسال میکند (مثال خام):
Host: example.com
Connection: keep-alive
Cache-Control: max-age=0
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توضیح: این بلوک نمایش دهندهٔ هدرهایی است که یک مرورگر واقعی ارسال میکند. اگر میخواهی هدرها را در درخواستهایت تقلید کنی، از ترکیبهای واقعی مانند بالا استفاده کن و برای هر درخواست ترکیبها را کمی تغییر بده.
مثال عملی با httpx (حفظ ترتیب هدرها با استفاده از لیست از تاپلها):
import httpx
headers = [
("Host", "example.com"),
("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ..."),
("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"),
]
with httpx.Client() as client:
resp = client.get("https://example.com/", headers=headers)
print(resp.status_code)
print(resp.headers.get('content-type'))توضیح کد:
- ورودی: آدرس URL و لیست headers به صورت لیست از تاپلها تا ترتیب حفظ شود.
- عملکرد: با httpx.Client یک درخواست GET ارسال میشود که ترتیب هدرها مطابق لیست است.
- خروجی: resp.status_code و هدرهای پاسخ؛ میتوانی محتوای HTML را پردازش کنی.
نکات عملی:
- از کلیدواژههای واقعی مرورگر استفاده کن و هر چند وقت یکبار user-agent را بهروزرسانی یا متنوع کن.
- برخی کلاینتها مانند requests ترتیب هدرها را بازنویسی میکنند؛ اگر ترتیب برای سایت اهمیت دارد از httpx یا فرمتهایی که ترتیب را حفظ میکنند استفاده کن.
آیپیها و پراکسیها: تفاوت میان مقیاسپذیری و ریسک
اگر حجم درخواستها بالا رود، آیپی یکی از واضحترین شاخصها برای بلاک است. رفتار معمول کاربران حقیقی بهندرت شامل چندصد درخواست در ثانیه از یک آیپی واحد است.
انواع گزینههای رایج:
- لیست پراکسی رایگان (ریسک بالا، کارایی پایین)
- پراکسی دیتاسنتر (سریع، احتمال شناخته شدن بیشتر)
- پراکسیهای residential یا mobile (با رفتار طبیعیتر، گرانتر)
- APIهای پراکسی (مدیریت ساده و امکانات چرخش)
مدیریت پراکسیها باید شامل گردش (rotation)، تست سلامت، blacklist/whitelist و تنوع شبکهای (subnetهای مختلف) باشد.
مثال سادهٔ گردش پراکسی و retry با backoff در پایتون (همزمانی با محدودکننده):
import asyncio
import random
import httpx
PROXIES = [
"http://user:pass@10.0.0.1:3128",
"http://user:pass@10.0.0.2:3128",
# ...
]
async def fetch(url):
for attempt in range(4):
proxy = random.choice(PROXIES)
try:
async with httpx.AsyncClient(proxies=proxy, timeout=10.0) as client:
r = await client.get(url)
r.raise_for_status()
return r.text
except Exception as e:
# اگر پراکسی بد است آن را کارشناسی کن یا از لیست حذف کن
await asyncio.sleep(2 ** attempt + random.random())
raise RuntimeError("All proxies failed")
# استفاده نمونه
# asyncio.run(fetch("https://example.com/"))توضیح کد:
- ورودی: لیست PROXIES و آدرس URL.
- عملکرد: برای هر تلاش یک پراکسی تصادفی انتخاب میشود. در صورت خطا exponential backoff اعمال میشود.
- خروجی: متن صفحه یا خطا در صورت شکست همهٔ تلاشها.
نکات عملی:
- پراکسیهای متنوع (شبکههای متفاوت) از شانس بلاک شدن کلی کم میکنند.
- پایش (monitoring) رفتار هر پراکسی برای حذف سریع پراکسیهای بد ضروری است.
پروفایلسازی درخواست: شبیهسازی رفتار انسانی
ساختار URL، الگوی درخواست و مکان جغرافیایی درخواستها سه عامل مهم در باورپذیری رفتار کاربر هستند. ارسال درخواستهای پیاپی و با نظمِ ریاضی (مثلاً پیمایش دقیق صفحات بهصورت ترتیبی و با فاصلهٔ همیشه یک ثانیه) رفتار ربات را افشا میکند.
چند قاعدهٔ کاربردی:
- از URLهایی استفاده کن که کاربران واقعی میبینند، نه کوتاهترین شناسهها.
- الگوهای تصادفی در انتخاب صفحه/محصول و فاصلهٔ بین درخواستها (متغیر بین ثانیه تا دقیقه) به طبیعیتر نشاندادن ترافیک کمک میکند.
- از پراکسیهایی با لوکیشن منطقی برای سایت هدف استفاده کن (مثلاً برای سایتهای منطقهای از پراکسی همان منطقه استفاده کن).
نمونهٔ پیادهسازی ساده برای randomize ترتیب و تأخیر:
import random
import time
items = list(range(1, 1000))
random.shuffle(items)
for i in items:
# کار پردازش آیتم i
delay = random.uniform(0.5, 4.0) # بین نیم تا چهار ثانیه
time.sleep(delay)توضیح:
- ورودی: لیست آیتمها
- عملکرد: جابجایی تصادفی لیست و خوابهای تصادفی بین درخواستها برای شبیهسازی رفتار انسانی
- خروجی: توالی درخواستهایی با فواصل متغیر
Fingerprint مرورگر و استفاده از headless browser
استفاده از مرورگرهای هدلس مانند Puppeteer، Playwright یا Selenium معمولاً طبیعیتر از کتابخانههای HTTP است، اما خودشان نشتیهایی دارند که سایتها میتوانند تشخیص دهند.
دو اصل مهم:
- رفع نشتیها (patch کردن APIها یا استفاده از پلاگینهای stealth)
- همخوانسازی هویت مرورگر با هدرها و پراکسیها
نمونهٔ Playwright (پایتون) با تنظیم user-agent، زبان و viewport:
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
context = browser.new_context(
user_agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ...",
locale="en-GB",
timezone_id="Europe/London",
viewport={"width": 1280, "height": 800},
java_script_enabled=True,
)
page = context.new_page()
page.goto('https://example.com/')
print(page.title())
browser.close()توضیح کد:
- ورودی: گزینههای context از جمله user_agent، locale و viewport.
- عملکرد: یک مرورگر کروم هدلس اجرا میشود و با مشخصات دادهشده به صفحه هدایت میشود.
- خروجی: عنوان صفحه چاپ میشود؛ میتوان رفتار محتوای جاوااسکریپت را تست کرد.
نکات عملی برای headless:
- همیشه نسخهٔ stealth یا روشهایی برای رفع نشتیها را در نظر بگیر (مثلاً کتابخانههای معروف stealth برای هر فریمورک).
- هویت ارائه شده در هدرها، UA و اطلاعات مرورگر باید یکدست باشد؛ ناهماهنگیها احتمال شناسایی را افزایش میدهد.
TLS و TCP/IP fingerprinting
علاوه بر هدرها و fingerprint مرورگر، TLS Client Hello و TCP/IP stack هم میتوانند امضای مشخصی داشته باشند. سایتهای پیشرفته با تحلیل TLS fingerprinting یا رفتار TCP میتوانند ترافیک غیرمرورگری را فیلتر کنند.
راهبردها:
- برای مواجهه با TLS fingerprinting یا TLS validation سختگیرانه، استفاده از مرورگر واقعی یا پراکسیهایی که TLS مرورگر را بازتولید میکنند قابل اعتمادتر است.
- در سطوح پایینتر میتوان کتابخانههایی را استفاده کرد که قادر به سفارشیسازی Client Hello و cipher suiteها هستند، اما این کار پیچیده و پرریسک است.
امنیت، اخلاق و قوانین
همواره از قوانین سایتها، شرایط استفاده و قوانین محلی تبعیت کن. حتی اگر از تکنیکهای فنّی استفاده میکنی، باید مطمئن شوی که فعالیتت قانونی و اخلاقی است. نکات امنتی تکنیکی:
- اطلاعات حساس (کلمه عبور پراکسی، API key) را در محیط امن و متغیرهای محیطی نگهداری کن، نه متن ساده در کد.
- تعداد دفعات تلاش و حافظه خطا (logging) را محدود کن تا افشای اطلاعات حساس در لاگ رخ ندهد.
جمعبندی و نکات عملی فوری
چکلیست کوتاه برای تولید اسکریپر مقاوم:
- هدرها را با الگوهای مرورگر واقعی طراحی کن و ترتیب هدرها را حفظ کن.
- در مقیاس از پراکسیهای متنوع با مدیریت سلامت و چرخش استفاده کن.
- الگوهای درخواست و URLها را طبیعی کن؛ از رفتار انسانی تقلید کن (تاخیرها، انتخاب تصادفی).
- اگر از مرورگر هدلس استفاده میکنی، از نسخههای stealth و همخوانسازی کامل هویت استفاده کن.
- در صورت مواجهه با TLS/TCP fingerprinting از مرورگر واقعی یا پراکسیهای سطح بالا استفاده کن.
این مهارتها را ترکیب کن: بهینهسازی هدر، پراکسیگذاری هوشمند و شبیهسازی رفتار انسانی با هم بیشترین تاثیر را در کاهش بلاک شدن دارند. شروع کن با یک پیادهسازی ساده (httpx + چرخش پراکسی + تاخیرهای تصادفی) و سپس سراغ headless/stealth و بهبود TLS برو.
آسان اسکریپ را در گوگل بهعنوان منبع ترجیحی انتخاب کن
مقالههای جدید ما زودتر و پررنگتر در نتایج گوگل و Discover برایت نمایش داده میشود. افزودن از تنظیمات گوگل





