

وبسایتهای مدرن از مکانیزمهای پیچیدهای برای شناسایی و مسدودسازی دسترسیهای خودکار استفاده میکنند. در این مقاله بهزبان فارسی یک راهنمای عملی و فنی برای «وب اسکریپینگ» و «اسکریپ کردن» دادهها تهیه کردهام که مناسب توسعهدهندگان پایتون در سطح متوسط است. پس از خواندن این مقاله میدانید چه روشهایی برای دور زدن محافظتها وجود دارد، هر روش چه مزایا و معایبی دارد و چگونه با مثالهای کد میتوانید آنها را پیاده کنید.
پیش از هر تلاش اسکریپ، باید بفهمیم سایت هدف چگونه رفتار را اندازهگیری و امتیازدهی میکند. شایعترین تکنیکها عبارتاند از:
شناخت این مکانیزمها کمک میکند تا روش مناسب (مثلاً تغییر هدرها، استفاده از پروکسی یا سراغ یک مرورگر headless رفتن) را انتخاب کنیم.
ایده کلی: با تغییر و چرخش هدرها و User-Agent سعی میکنیم درخواستهای خود را شبیه درخواستهای انسانی کنیم تا تشخیص بات سختتر شود.
مثال عملی در پایتون با requests. این قطعه کد یک لیست از User-Agentها را نگه میدارد و برای هر درخواست بهصورت تصادفی یکی انتخاب میکند.
import random
import requests
USER_AGENTS = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ... Chrome/91.0',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ... Chrome/91.0',
# لیست را واقعیتر و بزرگتر کنید
]
def fetch(target_url):
"""ورودی: target_url (رشته)
خروجی: محتوای HTML صفحه یا None در صورت خطا
نقش: ارسال یک GET با User-Agent تصادفی"""
headers = {
'User-Agent': random.choice(USER_AGENTS),
'Accept-Language': 'en-US,en;q=0.9',
# سایر هدرهای مشابه مرورگر را اضافه کنید
}
resp = requests.get(target_url, headers=headers, timeout=15)
resp.raise_for_status()
return resp.text
توضیح خطبهخط:
نکات مهم و محدودیتها:
چالش: وقتی درخواستها از یک آدرس IP ثابت ارسال شوند، احتمال بلاک بالا میرود. راهحل: با استفاده از پروکسیها IP را تغییر دهید.
نمونه سادهٔ چرخش پروکسی در پایتون (با requests):
PROXIES = [
{'http': 'http://USER:PASS@PROXY1', 'https': 'http://USER:PASS@PROXY1'},
{'http': 'http://USER:PASS@PROXY2', 'https': 'http://USER:PASS@PROXY2'},
]
def fetch_via_proxy(target_url):
proxy = random.choice(PROXIES)
resp = requests.get(target_url, headers={'User-Agent': random.choice(USER_AGENTS)}, proxies=proxy, timeout=20)
resp.raise_for_status()
return resp.text
توضیح:
مثال استفاده از Playwright (پایتون) با پروکسی برای رندر جاوااسکریپت:
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(proxy={
'server': 'PROXY_HOST:PORT',
'username': 'PROXY_USER',
'password': 'PROXY_PASS'
}, headless=True)
page = browser.new_page()
page.goto('TARGET_URL', timeout=30000)
html = page.content()
browser.close()
این روش برای سایتهایی که نیاز به اجرای JS دارند بسیار مفید است؛ پروکسی را میتوانید بهصورت پویا برای هر instance انتخاب کنید.
ایده: از مرورگرهایی استفاده کنید که رفتار انسان را بهتر شبیهسازی کنند تا جاوااسکریپتها و تعاملات را پاس کنند.
نمونه با Playwright (پایتون) — مناسب برای صفحات دینامیک:
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
context = browser.new_context(
user_agent='A realistic UA string here',
viewport={'width': 1280, 'height': 800}
)
page = context.new_page()
page.goto('TARGET_URL')
# تعاملات: کلیک، اسکرول، پر کردن فرم
page.wait_for_timeout(2000)
html = page.content()
browser.close()
همچنین ابزارهای Node.js مثل puppeteer-extra با پلاگین stealth معروف هستند. نمونهٔ کوتاه جاوااسکریپت برای مراجعۀ سریع:
const puppeteer = require('puppeteer-extra')
const StealthPlugin = require('puppeteer-extra-plugin-stealth')
puppeteer.use(StealthPlugin())
;(async () => {
const browser = await puppeteer.launch({ headless: true })
const page = await browser.newPage()
await page.goto('TARGET_URL')
// استخراج دادهها
await browser.close()
})();
توضیح: پلاگین استیلث سعی میکند نشانههای اتومات بودن را تغییر دهد (navigator.webdriver، افزونهها، WebGL، و غیره). استفاده از چنین ابزارهایی در کنار پروکسی توصیه میشود.
بهجای ساختن تمام اجزا از صفر، میتوانید از ارائهدهندگان پروکسی و سرویسهای «Anti-Bot Bypass» استفاده کنید که راهحلهای ترکیبی (پروکسی مسکونی + شبیهسازی مرورگر + حل چالشها) ارائه میکنند. نامهایی که در صنعت رایجاند شامل ScrapeOps، BrightData، Oxylabs و Zyte هستند.
مزایا:
معایب:
نمونهٔ فراخوان API ساده (پایتون) با axios معادل requests — توجه کنید که باید مقادیر توکن و پارامترها را مطابق سرویس جایگزین کنید:
import requests
API_KEY = 'YOUR_API_KEY'
params = {
'api_key': API_KEY,
'url': 'TARGET_URL',
'bypass': 'cloudflare_level_1' # مثال پارامتر سمت سرویس
}
resp = requests.get('PROXY_API_ENDPOINT', params=params, timeout=30)
print(resp.text)
این الگو به سرویس مدیریتشده اجازه میدهد تا با توجه به دامنهٔ هدف، استراتژی مناسب (پروکسی، مرورگر واقعی، حل CAPTCHA و...) را به کار ببندد.
چالش: CAPTCHAها عمداً برای جدا کردن انسان از ربات طراحی شدهاند. راهحلهای متداول استفاده از سرویسهای حل CAPTCHA است که یا نیروی انسانی یا الگوریتم دارند.
مثال با کتابخانه 2captcha برای پایتون:
from twocaptcha import TwoCaptcha
solver = TwoCaptcha('TWO_CAPTCHA_API_KEY')
try:
result = solver.recaptcha(sitekey='RECAPTCHA_SITEKEY', url='PAGE_WITH_RECAPTCHA')
token = result['code']
# ارسال توکن به فرم یا API صفحه
except Exception as e:
print('CAPTCHA error:', e)
توضیح: ورودیها شامل sitekey و آدرس صفحه هستند. خروجی یک توکن است که باید در فیلد مربوطه در صفحه قرار گیرد. هزینه و زمان حل بسته به سرویس و نوع CAPTCHA متغیر است.
نکتهٔ اخلاقی و قانونی: استفاده از خدمات حل CAPTCHA ممکن است با مقررات برخی سایتها در تضاد باشد؛ همیشه موارد حقوقی را بررسی کنید.
اگر دادهٔ شما میتواند اندکی قدیمی باشد، گرفتن نسخهٔ کششدهٔ یک صفحه (مثلاً نسخههایی که موتورهای جستجو نگهداری میکنند) راهکار سریع و سبکتری است. مزایا: بسیاری از دفاعها در نسخهٔ کش وجود ندارند. معایب: دادهها ممکن است بهروز نباشند و همه صفحات کش نمیشوند.
الگو: ابتدا بررسی کنید صفحه کش دارد یا نه؛ سپس آن را بخوانید. اگر بهروزی مهم است از این روش صرفنظر کنید.
این روش شامل تحلیل عمقی رفتارهای سمت سرور و کلاینت سایت هدف برای پیدا کردن شکافهایی است که بتوان از آنها استفاده کرد. مثالها: شبیهسازی TLS fingerprints، بازسازی توالی درخواستهای جاوااسکریپت، یا بازتولید تعاملات DOM.
مزایا و معایب:
این رویکرد برای تیمهایی مناسب است که در سطوح پایین شبکه و مرورگر تخصص دارند و ملاحظات حقوقی را بررسی کردهاند.
گام 1 — تلاش با requests و BeautifulSoup (معادل cheerio در Node): در بعضی صفحات ساده، همین روش کافی است. کد نمونه:
import requests
from bs4 import BeautifulSoup
resp = requests.get('TARGET_URL', headers={'User-Agent': random.choice(USER_AGENTS)})
soup = BeautifulSoup(resp.text, 'html.parser')
print(soup.title.string)
نتیجهٔ ممکن: اگر صفحه محتوای استاتیک داشته باشد یا سایت اجازهٔ ایندکس ساده را بدهد، همین کافیست. در غیر این صورت به روشهای دیگر نیاز است.
گام 2 — استفاده از پروکسی چرخان و مرورگر headless: اگر سایت دارای حفاظتهای Cloudflare یا شبیه آن باشد، ترکیب Playwright + پروکسی یا استفاده از سرویسهای مدیریتشده معمولاً موفق است.
جمعبندی مطالعهٔ موردی: ترکیب روشها (هدر بهینه، پروکسی، مرورگر headless) بیشترین شانس موفقیت را دارد؛ اما هزینه، مقیاسپذیری و نگهداری را نیز مد نظر قرار دهید.
برای موفقیت در وب اسکریپینگ باید بهصورت ترکیبی عمل کنید: بهینهسازی هدرها، چرخش پروکسی، استفاده از مرورگرهای headless تقویتشده و در صورت نیاز سرویسهای مدیریتشده یا حل CAPTCHA. هر روش مزایا و هزینههای خودش را دارد؛ انتخاب مناسب بستگی به حساسیت سایت هدف، میزان ضرورت بهروزرسانی داده و منابع شما دارد.
پیشنهاد عملی: برای شروع یک پروتوتایپ کوچک با requests و هدرهای بهینه بسازید؛ اگر شکست خورد، بهتدریج Playwright و پروکسی را اضافه کنید و در نهایت در صورت نیاز سرویسهای مدیریتشده را آزمایش کنید.


