← بازگشت به وبلاگ

خطای ۴۲۹ در پارس کردن Wildberries و Ozon: ۶ دلیل که با تغییر پروکسی حل نمی‌شود

پروکسی را تغییر می‌دهید، اما خطای ۴۲۹ همچنان وجود دارد؟ به بررسی ۶ دلیل فنی خطای Too Many Requests می‌پردازیم که با تغییر آدرس IP حل نمی‌شوند.

📅۵ مهر ۱۴۰۵

شما پروکسی را تغییر می‌دهید، یک مجموعه جدید از IP‌ها می‌خرید، اما پارسر همچنان با خطای 429 درخواست‌های زیاد سقوط می‌کند؟ این یک وضعیت کلاسیک است: 70٪ از موارد مسدود شدن به IP مربوط نمی‌شود، بلکه به نحوه شکل‌گیری خود درخواست مربوط است. شش دلیل واقعی را بررسی می‌کنیم که به خاطر آن‌ها وب‌سایت همچنان شما را حتی پس از تغییر پروکسی مسدود می‌کند — و در هر مورد چه کار باید کرد.

خطای 429 چه معنایی دارد و چرا پروکسی درمان نیست

کد HTTP 429 درخواست‌های زیاد به طور رسمی به معنای «حد مجاز درخواست‌ها تجاوز شده است» است. اما در عمل وب‌سایت‌ها — به ویژه Wildberries، Ozon، Avito، یاندکس مارکت — از این کد به عنوان سیگنال جهانی «ما فکر می‌کنیم شما ربات هستید» استفاده می‌کنند. دلیل می‌تواند در فرکانس درخواست‌ها باشد، اما به همان اندازه ممکن است به هدرها، اثر انگشت مرورگر، عدم وجود سشن کوکی یا محدودیت‌هایی که به IP مربوط نیستند، بلکه به حساب شما مربوط می‌شوند، بستگی داشته باشد.

به همین دلیل است که تغییر پروکسی اغلب کمک نمی‌کند: اگر سیستم IP را مسدود کند، بلکه الگوی درخواست (اثر انگشت، هدرها، سرعت کلیک‌ها) را مسدود کند، شما از IP جدید نیز پس از چند دقیقه همان 429 را دریافت خواهید کرد. هر دلیل را به طور دقیق بررسی می‌کنیم و نشان می‌دهیم که چگونه آن را بدون خرید مجموعه جدید پروکسی بررسی و رفع کنیم.

مهم: پروکسی‌ها همچنان ابزار ضروری هستند — اما فقط به عنوان بخشی از سیستم، نه به عنوان تنها راه حل. IP‌های مسکونی و موبایل احتمال قرار گرفتن در لیست سیاه به خاطر اعتبار IP را کاهش می‌دهند، اما از مسدود شدن به خاطر رفتار یا هدرها جلوگیری نمی‌کنند.

دلیل 1: فرکانس درخواست‌ها بسیار بالا است

واضح‌ترین، اما همچنین اغلب به اشتباه تشخیص داده شده است. بسیاری فکر می‌کنند: «چون من پروکسی را برای هر درخواست تغییر می‌دهم — فرکانس مهم نیست». این نادرست است. سیستم‌های ضد ربات مدرن (به عنوان مثال، در Wildberries و Ozon راه‌حل‌های سطح Cloudflare یا WAF‌های خودشان وجود دارد) نه تنها فرکانس از یک IP را تجزیه و تحلیل می‌کنند، بلکه بار کلی بر روی یک نقطه پایانی API یا صفحه محصول در یک واحد زمان را از تمام منابع به همراه سیگنال‌های رفتاری نیز بررسی می‌کنند.

اگر پارسر شما 50-100 درخواست در ثانیه به یک بخش خاص از کاتالوگ ارسال کند، سیستم یک افزایش غیرعادی ترافیک را مشاهده می‌کند، صرف نظر از اینکه چقدر IP‌های مختلف استفاده می‌کنید. راه حل — تغییر پروکسی نیست، بلکه پیاده‌سازی تأخیرهای مصنوعی (throttling) بین درخواست‌ها است: 1-3 ثانیه تأخیر تصادفی به جای فاصله ثابت، به علاوه backoff نمایی هنگام دریافت 429 (افزایش دو برابری زمان وقفه پس از هر مسدود شدن).

import time, random

def safe_request(session, url):
    for attempt in range(5):
        response = session.get(url)
        if response.status_code == 429:
            wait = (2 ** attempt) + random.uniform(0, 1)
            time.sleep(wait)
            continue
        return response
    return None

اگر شما از یک پارسر آماده بدون کد استفاده می‌کنید (به عنوان مثال، یک سرویس ابری برای نظارت بر قیمت‌ها)، تنظیمات فاصله بین درخواست‌ها را بررسی کنید — در بیشتر این ابزارها یک اسلایدر «سرعت اسکن» وجود دارد. کاهش سرعت به میزان 30-40٪ اغلب 429 را به طور کامل حذف می‌کند، حتی بدون تغییر پروکسی.

دلیل 2: هدرهای نادرست یا غیاب هدرها

بسیاری از پارسرها درخواست‌ها را با حداقل مجموعه‌ای از هدرها ارسال می‌کنند یا از User-Agent کتابخانه به طور پیش‌فرض استفاده می‌کنند (به عنوان مثال، «python-requests/2.28.1»). چنین هدرهایی به سرعت ربات را شناسایی می‌کنند — یک مرورگر واقعی ده‌ها هدر ارسال می‌کند: Accept، Accept-Language، Accept-Encoding، Sec-Fetch-*، Referer و دیگران به ترتیب خاصی.

Wildberries و Ozon مجموعه هدرها را با «اثر انگشت» مورد انتظار یک مرورگر واقعی Chrome یا Safari مقایسه می‌کنند. اگر هدرها خیلی کم باشند، در آن ترتیب نباشند یا User-Agent با سایر پارامترها مطابقت نداشته باشد (به عنوان مثال، Chrome در ویندوز اعلام شده، اما اثر انگشت TLS شبیه به Python است) — درخواست به 429 مسدود می‌شود، صرف نظر از IP.

هدر خطای معمولی راه حل
User-Agent نسخه قدیمی یا به وضوح رشته کتابخانه‌ای UA واقعی Chrome/Safari، چرخش از مجموعه
Accept-Language غیاب یا عدم تطابق با موقعیت جغرافیایی IP ru-RU برای بازارهای روسی
Referer خالی، در حالی که انتقال واقعی همیشه با Referer است صفحه قبلی کاتالوگ را مشخص کنید
Sec-Fetch-* کاملاً غیاب دارند (غیر کلاینت مرورگر) مجموعه کامل را از DevTools مرورگر واقعی کپی کنید

ساده‌ترین راه این است که مجموعه کامل هدرها را از تب Network در DevTools مرورگر واقعی کپی کنید، صفحه مورد نظر را به صورت دستی باز کنید و از همین مجموعه در پارسر استفاده کنید — با توجه به ترتیب هدرها، اگر کتابخانه این اجازه را بدهد (به عنوان مثال، curl_cffi یا httpx با ترتیب مشخص).

دلیل 3: عدم چرخش سشن‌ها و کوکی‌ها

خطایی که اغلب نادیده گرفته می‌شود: پارسر برای هر درخواست IP را تغییر می‌دهد، اما از یک سشن کوکی یکسان استفاده می‌کند یا اصلاً کوکی‌ها را ذخیره نمی‌کند. یک کاربر واقعی در اولین بازدید مجموعه‌ای از کوکی‌ها (توکن‌های سشن، شناسه‌های دستگاه، برچسب‌های ضد ربات مانند Cloudflare __cf_bm یا مشابه آن‌ها در Ozon/WB) را دریافت می‌کند و از آن‌ها در تمام درخواست‌های بعدی در طول سشن استفاده می‌کند.

اگر شما درخواست را بدون کوکی‌هایی که از صفحه «گرم» دریافت شده ارسال کنید، سیستم ضد ربات یک سشن «صفر» را مشاهده می‌کند — و این بلافاصله مشکوک است، به ویژه هنگام تماس با نقاط پایانی API به طور مستقیم، بدون عبور از صفحه اصلی. راه حل — شبیه‌سازی سناریوی کامل: ابتدا صفحه اصلی یا صفحه دسته‌بندی را بارگذاری کنید، کوکی‌ها را دریافت کنید، 1-2 ثانیه صبر کنید و سپس به API یا کارت محصول مورد نظر مراجعه کنید، در حالی که کوکی‌ها را در همان سشن در طول زنجیره درخواست‌ها حفظ می‌کنید.

import requests

session = requests.Session()
session.headers.update({
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)...",
    "Accept-Language": "ru-RU,ru;q=0.9"
})

# گرم کردن سشن
session.get("https://www.wildberries.ru/catalog/0/search.aspx")
time.sleep(1.5)

# درخواست اصلی با کوکی‌ها
response = session.get(target_url)

اگر شما از مرورگر ضد شناسایی مانند Dolphin Anty یا AdsPower برای نظارت بر کارت‌های محصول به صورت دستی یا از طریق اتوماسیون داخلی استفاده می‌کنید، اطمینان حاصل کنید که پروفایل کوکی‌ها را بین سشن‌ها حفظ می‌کند و هر بار «از ابتدا» شروع نمی‌شود — این نیز سیستم را مشکوک می‌کند.

دلیل 4: رفتار شبیه به ربات

حتی با هدرها و کوکی‌های ایده‌آل، پارسر می‌تواند با الگوهای رفتاری خود را شناسایی کند: ترتیب خطی دقیق در دسترسی به محصولات (بر اساس افزایش ID)، فاصله یکسان بین درخواست‌ها تا میلی‌ثانیه، عدم وجود درخواست‌های «زائد» برای استاتیک (تصاویر، CSS، JS) که مرورگر معمولی به طور خودکار بارگذاری می‌کند.

سیستم‌های پیشرفته حفاظت Wildberries و Ozon نه تنها درخواست‌های HTTP را تجزیه و تحلیل می‌کنند، بلکه بررسی می‌کنند که آیا JavaScript در صفحه اجرا شده است (از طریق شناسایی headless)، آیا «ماوس» حرکت کرده است، آیا اسکرول وجود داشته است. اگر شما درخواست‌های خالص HTTP را بدون رندر کردن JS انجام دهید، و وب‌سایت انتظار اجرای اسکریپت برای دریافت توکن (به عنوان مثال، چالش ضد ربات جاوااسکریپت) را داشته باشد، درخواست بدون اجرای این اسکریپت به طور خودکار 429 یا 403 دریافت می‌کند.

راه حل بستگی به مقیاس دارد: برای حجم‌های کوچک، استفاده از مرورگر headless (Playwright، Puppeteer) با شبیه‌سازی حرکات ماوس و تأخیرهای تصادفی مناسب است. برای تجزیه صنعتی — تصادفی‌سازی ترتیب مرور محصولات، افزودن «نویز» به صورت درخواست‌های منابع ثانویه، و تنوع در فاصله‌های زمانی بر اساس توزیع نرمال، نه بر اساس یک گام ثابت.

دلیل 5: اثر انگشت TLS/JA3 و HTTP/2

این یکی از «ناشناس‌ترین» دلایل فنی است که 90٪ از افرادی که بدون آموزش فنی عمیق به تجزیه می‌پردازند، از آن بی‌خبرند. هر کلاینت TLS (کتابخانه requests، curl، urllib) هنگام برقراری اتصال HTTPS یک اثر انگشت منحصر به فرد به جا می‌گذارد — مجموعه‌ای از رمزگذاری‌های پشتیبانی شده، نسخه‌های پروتکل، و گسترش‌های TLS. این اثر انگشت به نام اثر انگشت JA3/JA4 شناخته می‌شود.

سیستم‌های ضد ربات سطح Cloudflare، Akamai و راه‌حل‌های داخلی بازارهای بزرگ اثر انگشت JA3 را با پایگاه داده ربات‌های شناخته شده و کتابخانه‌ها مقایسه می‌کنند. requests استاندارد Python یا ماژول https Node.js دارای اثر انگشت قابل شناسایی آسانی هستند که کاملاً با اثر انگشت واقعی Chrome متفاوت است. حتی با هدرها و کوکی‌های ایده‌آل، درخواست در سطح TLS-handshake مسدود می‌شود، قبل از اینکه سرور هدرهای HTTP را ببیند.

علاوه بر این، بسیاری از بازارها به HTTP/2 با پارامترهای خاص (ترتیب فریم‌های SETTINGS، اولویت‌بندی جریان‌ها) نیاز دارند — کتابخانه‌های مبتنی بر HTTP/1.1 به طور خودکار در این زمینه شناسایی می‌شوند. راه حل — استفاده از کتابخانه‌هایی که اثر انگشت مرورگر واقعی را شبیه‌سازی می‌کنند: curl_cffi (اثر انگشت TLS Chrome را شبیه‌سازی می‌کند)، tls-client، یا مرورگرهای headless کامل مبتنی بر Chromium که به طور تعریف شده «اثر انگشت واقعی» را ارائه می‌دهند.

pip install curl_cffi

مثال: curl_cffi.requests.get(url, impersonate="chrome120") — کتابخانه به طور خودکار اثر انگشت TLS را جایگزین می‌کند که با Chrome 120 واقعی یکسان است.

دلیل 6: محدودیت در سطح حساب یا کلید API

اگر شما از طریق API رسمی یا نیمه‌رسمی بازار (به عنوان مثال، API فروشنده Wildberries یا Ozon Seller API) کار می‌کنید، 429 ممکن است به IP مربوط نباشد، بلکه به خود حساب فروشنده یا توکن API مربوط باشد. در این صورت تغییر پروکسی به طور کلی بی‌فایده است — محدودیت در سمت سرور به شناسه حساب شما مرتبط است و هر IP از این حساب همان محدودیت را دریافت می‌کند.

این وضعیت برای فروشندگانی که همزمان قیمت‌های رقبا را از طریق پنل کاربری نظارت می‌کنند و API را برای بارگذاری موجودی‌ها می‌کشند، معمول است — هر دو جریان درخواست‌ها به محدودیت کلی حساب اضافه می‌شوند. راه حل — توزیع بار بر اساس زمان، استفاده از سهمیه‌های رسمی API به طور اقتصادی‌تر (ذخیره‌سازی داده‌هایی که هر دقیقه تغییر نمی‌کنند)، و برای نظارت خالص بر قیمت‌های رقبا از یک جریان درخواست غیرمجاز جداگانه استفاده کنید که به حساب فروشنده مرتبط نیست.

بررسی این موضوع ساده است: اگر 429 حتی با درخواست از یک IP جدید و بدون یک کوکی از سشن‌های قبلی ادامه یابد، اما شما در یک تب دیگر در پنل کاربری وارد شده‌اید — احتمالاً محدودیت به حساب مربوط است.

چگونه دلیل واقعی را تشخیص دهیم

قبل از تغییر زیرساخت، تشخیص را طبق الگوریتم زیر انجام دهید. ابتدا صفحه را به صورت دستی در یک مرورگر معمولی باز کنید و اطمینان حاصل کنید که 429 در رفتار واقعی ایجاد نمی‌شود — این تأیید می‌کند که مشکل در سمت پارسر است، نه مسدودیت جهانی منطقه.

سپس هدرهای پارسر خود را با هدرهای مرورگر واقعی از طریق DevTools مقایسه کنید (زیرمجموعه Network → Copy as cURL). اگر تفاوت حداقلی باشد، اثر انگشت TLS را از طریق سرویس‌هایی مانند tls.peet.ws بررسی کنید — درخواست خود را با کتابخانه‌تان ارسال کنید و هاش JA3 را با هاش مرورگر مرجع مقایسه کنید. اگر درخواست در مرحله TLS-handshake سقوط کند (اتصال قبل از دریافت پاسخ HTTP قطع شود) — دلیل در اثر انگشت است، نه در فرکانس یا هدرها.

سپس بررسی کنید که آیا محدودیت به IP یا به حساب مربوط است: یک درخواست از یک IP جدید و بدون مجوز ارسال کنید. اگر 429 ناپدید شد — مشکل در اعتبار IP قبلی یا فرکانس از این آدرس بود. اگر 429 باقی ماند — دلیل را در هدرها، TLS یا رفتار جستجو کنید، نه در پروکسی.

چک‌لیست رفع 429 بدون تغییر پروکسی

  1. تأخیرهای تصادفی 1-4 ثانیه بین درخواست‌ها به جای فاصله ثابت اضافه کنید.
  2. مجموعه کامل هدرهای مرورگر واقعی را کپی کنید، از جمله Sec-Fetch-* و Accept-Language.
  3. کوکی‌ها را در چارچوب یک سشن حفظ و منتقل کنید، از گرم کردن صفحه اصلی شروع کنید.
  4. اثر انگشت TLS کتابخانه خود را بررسی کنید — از curl_cffi یا مرورگر headless به جای کلاینت HTTP خالص استفاده کنید.
  5. ترتیب مرور صفحات را تصادفی کنید و درخواست‌های «نویز» به منابع استاتیک اضافه کنید.
  6. بار حساب API و نظارت غیرمجاز بر قیمت‌ها را به جریان‌های مختلف تقسیم کنید.
  7. هنگام دریافت 429، backoff نمایی را پیاده‌سازی کنید، نه تکرار فوری درخواست.
  8. فقط پس از بررسی تمام موارد بالا — پروکسی را تغییر دهید یا مجموعه IP را گسترش دهید.

کی پروکسی‌ها هنوز نیاز است و کدام را انتخاب کنیم

پس از رفع تمام شش دلیل، پروکسی‌ها همچنان عنصر مهمی از زیرساخت باقی می‌مانند — اما اکنون به عنوان ابزاری برای مقیاس‌پذیری، نه تنها راه حل برای مقابله با مسدودیت‌ها. اگر وظیفه شما نظارت همزمان بر هزاران کارت Wildberries و Ozon از کاربران «مجازی» مختلف است، به یک مجموعه IP با اعتبار خوب نیاز دارید تا تاریخچه مسدودیت‌ها را در یک آدرس انباشته نکنید.

برای نظارت انبوه بر قیمت‌ها و کاتالوگ‌های بازارها، بهترین گزینه پروکسی‌های مسکونی هستند — آن‌ها از IP‌های واقعی ارائه‌دهندگان خانگی استفاده می‌کنند، بنابراین سیستم‌های ضد ربات درخواست‌ها را به عنوان ترافیک خریداران عادی، نه مرکز داده، درک می‌کنند. این موضوع حیاتی است، زیرا Wildberries و Ozon مدت‌هاست که لیست سیاه IP‌های مرکز داده را حفظ می‌کنند.

اگر وظیفه به بررسی نسخه موبایل وب‌سایت، کار از طریق برنامه بازار یا آزمایش تبلیغات در TikTok Ads و Facebook Ads با دقت جغرافیایی تا سطح شهر مربوط باشد، پروکسی‌های موبایل مرتبط هستند — آن‌ها بالاترین سطح اعتماد را در اکثر سیستم‌های امنیتی دارند، زیرا IP‌ها متعلق به اپراتورهای واقعی تلفن همراه هستند.

برای وظایف کمتر حساس — به عنوان مثال، تجزیه کاتالوگ‌های باز بدون مجوز در حجم‌های کوچک — می‌توان از پروکسی‌های مرکز داده استفاده کرد: آن‌ها به طور قابل توجهی ارزان‌تر و سریع‌تر هستند، اما نیاز به تنظیم دقیق‌تری از هدرها و اثر انگشت TLS دارند، زیرا خودشان خطر بیشتری برای مشکوک شدن دارند.

نوع پروکسی کی 429 را حل می‌کند کی کمک نمی‌کند
مسکونی IP قبلاً به خاطر اعتبار در لیست سیاه است مسدود شدن به خاطر اثر انگشت TLS یا هدرها
موبایل بیشترین اعتماد IP برای سناریوهای حساس نیاز است محدودیت به حساب مربوط است، نه به IP
مرکز داده تجزیه ساده صفحات باز بدون مجوز سیستم‌های ضد ربات سختگیر با بررسی اعتبار دامنه‌ها

نتیجه‌گیری

خطای 429 هنگام تجزیه به ندرت با یک دکمه «تغییر پروکسی» حل می‌شود. در بیشتر موارد، مشکل در فرکانس درخواست‌ها، هدرهای ناقص، عدم وجود سشن کوکی، اثر انگشت TLS قابل شناسایی، الگوهای رفتاری یا محدودیت‌هایی است که به حساب مربوط می‌شوند، نه به IP. تشخیص را در هر یک از شش مورد این مقاله انجام دهید، قبل از اینکه بودجه خود را برای گسترش مجموعه پروکسی صرف کنید.

زمانی که بخش فنی به درستی تنظیم شده باشد — هدرها با مرورگر واقعی مطابقت داشته باشند، اثر انگشت TLS کتابخانه را شناسایی نکند، و درخواست‌ها رفتار طبیعی کاربر را شبیه‌سازی کنند — پروکسی‌ها به واقع ابزار مؤثری برای مقیاس‌پذیری می‌شوند. برای نظارت بر قیمت‌ها در Wildberries و Ozon در حجم‌های صنعتی، توصیه می‌کنیم با پروکسی‌های مسکونی شروع کنید: آن‌ها بهترین تعادل بین هزینه و سطح اعتماد سیستم‌های ضد ربات را ارائه می‌دهند.