خانه/مقالات/راهنمای سریع وب اسکریپینگ: حل CAPTCHA با NodeJS
پروکسی و چرخش IP
ضد بلاک (Anti-bot)
Playwright
برگشت به صفحه مقاله ها
راهنمای سریع وب اسکریپینگ: حل CAPTCHA با NodeJS

راهنمای سریع وب اسکریپینگ: حل CAPTCHA با NodeJS

این مقاله یک راهنمای فنی و مرحله‌به‌مرحله برای حل CAPTCHAها در پروژه‌های وب اسکریپینگ با NodeJS ارائه می‌دهد: از OCR با <strong>tesseract.js</strong> و اتوماسیون با <strong>playwright</strong> تا یکپارچه‌سازی سرویس‌های پولی، حل CAPTCHAهای صوتی و مدیریت پراکسی. نکات عملی، مثال‌های کد و توصیه‌های امنیتی/قانونی برای پیاده‌سازی پایدار و اخلاقی پوشش داده شده‌اند.
امیر حسین حسینیان
امیر حسین حسینیان
1404-09-29

مقدمه

در این راهنما عملی برای توسعه‌دهندگان پایتون/NodeJS اما با تاکید بر استفاده از NodeJS در زمینهٔ وب اسکریپینگ توضیح می‌دهیم چگونه با انواع CAPTCHAها برخورد کنید. بعد از خواندن این مقاله یاد می‌گیرید چه زمانی باید از اجتناب استفاده کنید، چه زمانی از OCR یا مدل‌های سفارشی بهره ببرید، چگونه سرویس‌های پولی را یکپارچه کنید و مثال‌های کد مرحله‌به‌مرحله برای playwright، tesseract.js و نمونهٔ تماس با API سرویس‌های حل CAPTCHA خواهید دید.

انواع CAPTCHA و چالش‌های فنی

CAPTCHAها شکل‌های متفاوتی دارند و هر کدام نیازمندی‌ها و سطح دشواری خاص خود را دارند:

  1. reCAPTCHA (v2 / v3) — معمولاً با data-sitekey در صفحه قرار می‌گیرد؛ رفتار کاربر را تحلیل می‌کند و به‌خاطر تعاملات پیچیدهٔ سمت کلاینت سخت‌تر قابل اتوماته کردن است.

  2. hCaptcha — مشابه reCAPTCHA اما منطق متفاوت و چیدمان دیگری دارد.

  3. تصویر متنی / Base64 — تصویر حاوی متن کدگذاری‌شده که با پردازش تصویر و OCR قابل حل است.

  4. اسلاید/پازل تعاملی — نیازمند تعامل پیچیدهٔ صفحه (Drag/Drop یا تشخیص لبه در پس‌زمینه)

  5. Audio CAPTCHA — فایل صوتی که باید به متن تبدیل شود؛ مناسب برای مدل‌های ASR یا سرویس‌های اختصاصی.

رویکردهای کلی برای مواجهه با CAPTCHA

چهار رویکرد اصلی وجود دارد که باید بسته به شرایط ترکیب کنید:

  • اجتناب (Avoidance): با شبیه‌سازی رفتار انسانی، چرخش پراکسی و نرخ درخواست مناسب، از دیده شدن توسط سیستم‌های ضدبات جلوگیری کنید.

  • سرویس‌های آماده (Third-party): ارسال چالش به سرویس‌هایی که با نیروی انسانی یا ML پاسخ می‌دهند (مثلاً سرویس‌های پولی). ساده، مقیاس‌پذیر اما هزینه‌بر و دارای نگرانی‌های حریم خصوصی.

  • OCR و ابزار متن‌باز: برای CAPTCHAهای متنی از tesseract.js یا OpenCV استفاده کنید؛ رایگان است اما برای CAPTCHAهای پیچیده کافی نیست مگر وقت زیادی صرف پردازش تصویر و تمیزسازی کنید.

  • سفارشی/ML: آموزش شبکه‌های عصبی اختصاصی یا استفاده از GAN برای تولید دادهٔ آموزشی؛ هزینه و پیچیدگی بالاست اما برای موارد خاص قابل دفاع است.

حل CAPTCHAهای متنی با Tesseract و Playwright

مراحل کلی برای حل یک CAPTCHA متنی روی یک صفحهٔ وب:

  1. با playwright صفحه را باز کنید و تصویر CAPTCHA را دانلود یا تبدیل به Base64 کنید.

  2. تصویر را با پردازش اولیه (آستانه‌گذاری، حذف نویز، resize) آماده کنید تا نرخ تشخیص OCR بالا برود.

  3. متن را توسط tesseract.js استخراج کنید و سپس آن را در فیلد مناسب صفحه قرار دهید.

نصب اولیه (دستورات اجرا در ترمینال):

npm install tesseract.js playwright

نمونهٔ کد ساده (خلاصه‌شده) که تصویر محلی را با Tesseract پردازش می‌کند:

const { createWorker } = require('tesseract.js');(async () => { const worker = await createWorker(); await worker.loadLanguage('eng'); await worker.initialize('eng'); const { data: { text } } = await worker.recognize('./captcha.png'); console.log('OCR result:', text); await worker.terminate();})();

توضیح خط‌به‌خط:

  • ورودی: مسیر فایل تصویر ('./captcha.png')

  • خروجی: رشتهٔ متن استخراج‌شده در text

  • هر مرحله: ساختن worker، بارگذاری زبان، فراخوانی recognize و سپس آزادسازی منابع.

نکات عملی: پیش‌پردازش تصویر اهمیت زیادی دارد (آستانه‌گذاری، تبدیل به خاکستری، حذف نویز). Tesseract برای CAPTCHAهای تحریف‌شده و نویزی به‌تنهایی معمولاً کافی نیست؛ در چنین مواردی ترکیب با OpenCV یا مدل ML لازم است.

یکپارچه‌سازی سرویس پولی – مثال 2captcha

وقتی دقت بالا و زمان قابل‌پیش‌بینی نیاز دارید، استفاده از سرویس‌های پولی (که معمولاً از نیروی انسانی یا مدل‌های اختصاصی استفاده می‌کنند) بهترین انتخاب است. مراحل کلی:

  1. ثبت‌نام و دریافت API key از سرویس.

  2. ارسال تصویر یا sitekey+URL (برای reCAPTCHA/hCaptcha) به API و دریافت پاسخ.

  3. وارد کردن پاسخ در فرم و ادامهٔ اسکریپ.

نصب کتابخانهٔ مشتری:

npm install 2captcha

مثال: ارسال تصویر محلی و قرار دادن پاسخ در صفحه با playwright:

const { chromium } = require('playwright');const Captcha = require('2captcha');const fs = require('fs');(async () => { const browser = await chromium.launch(); const page = await browser.newPage(); const solver = new Captcha.Solver('API_KEY'); // خواندن تصویر به صورت base64 const imageBase64 = fs.readFileSync('./demo.png', 'base64'); const result = await solver.imageCaptcha(imageBase64); // result.data شامل پاسخ است await page.fill('#captcha-input', result.data); await page.click('#submit'); await browser.close();})();

توضیح:

  • ورودی: کلید API و تصویر CAPTCHA (Base64)

  • خروجی: رشتهٔ پاسخ در result.data

  • ریسک‌ها: هزینه برای هر درخواست، همچنین وابستگی به سرویس بیرونی و نکات حریم خصوصی؛ همیشه کلید API را محرمانه نگه دارید و آن را در کد عمومی قرار ندهید.

حل reCAPTCHA و hCAPTCHA

برای این نوع CAPTCHAs که به‌صورت ویجت در صفحه قرار می‌گیرند باید مقدار data-sitekey را استخراج کنید و آن را همراه با آدرس صفحه به API ارسال نمایید. اگر از سرویس انسانی استفاده می‌کنید، معمولاً متدهای اختصاصی برای recaptcha و hcaptcha وجود دارد که sitekey و URL را می‌گیرند.

نکته فنی: sitekey در تگ‌های صفحه به‌صورت صریح قرار دارد و برای استخراجش کافی است DOM را بررسی یا با Playwright مقدار آن را بخوانید سپس به API ارسال کنید.

حل Audio CAPTCHAs

Audio CAPTCHAها معمولاً با ASR (Automatic Speech Recognition) قابل حل‌اند. اگر کتابخانه مشتری برای ارسال مستقیم وجود نداشته باشد، باید خودتان API را فراخوانی کنید:

const fetch = require('node-fetch');const fs = require('fs');const apiKey = 'API_KEY';async function submitAudio() { const audioBase64 = fs.readFileSync('./audio.mp3', 'base64'); const body = { clientKey: apiKey, task: { type: 'AudioTask', body: audioBase64, lang: 'en' } }; const res = await fetch('https://api.example.com/createTask', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) }); const data = await res.json(); return data.taskId; } async function fetchResult(taskId) { await new Promise(r => setTimeout(r, 10000)); const res = await fetch(`https://api.example.com/getResult?key=${apiKey}&id=${taskId}`); const data = await res.json(); console.log('Audio CAPTCHA result:', data); } (async () => { const id = await submitAudio(); await fetchResult(id); })();

توضیح و نکات:

  • روال: ارسال فایل صوتی (Base64) → دریافت taskId → انتظار و poll برای نتیجه.

  • محدودیت‌ها: کیفیت صدای CAPTCHA و زبان مهم است؛ در برخی موارد باید از مدل‌های ASR قوی یا پیش‌پردازش صوتی (نویزگیر، فیلتر فرکانسی) استفاده کنید.

جلوگیری از تریگر شدن CAPTCHA

بهترین استراتژی این است که اصلاً CAPTCHA را تریگر نکنیم. برخی تکنیک‌های عملی:

  1. شبیه‌سازی رفتار انسانی: تاخیرهای تصادفی بین کلیک‌ها و درخواست‌ها، حرکت موس شبیه‌سازی‌شده و پر کردن فرم به‌صورت انسانی.

  2. چرخش پراکسی و User-Agent: استفاده از استخر IP، روتیشن پراکسی و تغییر هدرهای مرورگر.

  3. حفظ سشن و کوکی: استفادهٔ مداوم از یک سشن و ذخیرهٔ کوکی‌ها برای جلوگیری از رفتار پراکندهٔ درخواست‌ها.

  4. محدودیت نرخ و backoff: رعایت نرخ معقول درخواست‌ها و استفاده از استراتژی‌های retry با افزایش فاصله (exponential backoff).

  5. استفاده از headful browser در موارد حساس: بعضی سایت‌ها رفتار headless را تشخیص می‌دهند؛ اجرای مرورگر با رابط گرافیکی یا شبیه‌سازی ویژگی‌های headful می‌تواند کمک کند.

پراکسی اجگِریتور: نمونهٔ استفاده با ScrapeOps

وقتی مدیریت پراکسی و چرخش برایتان چالش است، استفاده از یک پراکسی‌اجگِریتور می‌تواند ساده‌تر و مؤثرتر باشد؛ در این مثال نحوهٔ پیکربندی پراکسی در playwright را می‌بینیم (کلید API را محرمانه نگه دارید):

const playwright = require('playwright');(async () => { const PROXY_SERVER = 'proxy.example.com'; const PROXY_PORT = '5353'; const PROXY_USER = 'scrapeops.headless_browser_mode=true'; const PROXY_PASS = 'YOUR_API_KEY'; const browser = await playwright.chromium.launch({ headless: true, proxy: { server: `http://${PROXY_SERVER}:${PROXY_PORT}`, username: PROXY_USER, password: PROXY_PASS } }); const context = await browser.newContext({ ignoreHTTPSErrors: true }); const page = await context.newPage(); await page.goto('https://example.com', { timeout: 180000 }); const html = await page.content(); console.log('Page loaded length:', html.length); await browser.close(); })();

توضیح:

  • این الگو باعث می‌شود درخواست‌ها از طریق استخر پراکسی ارسال شوند و احتمال تریگر شدن CAPTCHA کاهش یابد.

  • ورودی‌ها: آدرس پراکسی، پورت و اطلاعات احراز هویت

  • خروجی: محتوای صفحه یا خطا در صورت بلوکه‌شدن؛ همیشه باید خطاها و timeouts را هندل کنید.

نکات امنیتی، عملکرد و پایداری

  • محدودیت‌های قانونی و اخلاقی: قبل از اسکریپ کردن هر سایت، قوانین استفاده و شرایط سرویس آن را بررسی کنید و از درخواست‌های غیرمجاز یا دورزدن محافظت‌ها خودداری کنید.

  • امنیت کلیدها: کلیدهای API را در محیط اجرا (ENV) یا سرویس مخفی‌ساز ذخیره کنید؛ در ریپازیتوری عمومی قرار ندهید.

  • مدیریت خطا و retry: برای هر تماس شبکه‌ای زمان‌سنج (timeout)، تعداد تلاش (retries) و استراتژی افزایش فاصله را پیاده‌سازی کنید.

  • مقیاس‌پذیری و concurrency: تعداد همزمانی را براساس ظرفیت پراکسی، سرعت سرویس حل CAPTCHA و قوانین سایت کنترل کنید تا از بلاک شدن جلوگیری شود.

  • لاگ و مانیتورینگ: خطاها، نرخ موفقیت حل CAPTCHA و زمان پاسخ سرویس‌ها را مانیتور کنید تا نقاط شکست را سریع پیدا کنید.

جمع‌بندی

در پروژه‌های وب اسکریپینگ، برخورد با CAPTCHA ترکیبی از پیشگیری (اجتناب)، استفاده از ابزارهای متن‌باز برای موارد ساده و سرویس‌های پولی یا مدل‌های تخصصی برای چالش‌های پیچیده است. همیشه ابتدا از روش‌های کم‌تهاجمی مانند شبیه‌سازی رفتار انسانی و پراکسی چرخشی استفاده کنید و تنها در صورت نیاز به دقت بیشتر، به سرویس‌های حل CAPTCHA یا مدل‌های ML متوسل شوید. رعایت قوانین و مسائل امنیتی را فراموش نکنید—کلیدها را امن نگه دارید، نرخ‌ها را کنترل کنید و مانیتورینگ را فعال کنید.

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