عندما يعترض اختبار reCAPTCHA أو Cloudflare Turnstile سكربت جمع البيانات المالية، لا يعني ذلك توقّف العملية. الحل أن تُدمج داخل السكربت آلية تعامل تلقائية تمرّ بأربع مراحل دون أي تدخل يدوي:
- اكتشف مفتاح الموقع (sitekey) في صفحة الهدف.
- أرسله إلى CaptchaAI واطلب حلّ الاختبار المطلوب.
- استطلع النتيجة دورياً حتى يجهز الرمز.
- أعد إرسال الطلب نفسه ومعه الرمز، فتستأنف عملية الجمع تلقائياً.
يطبّق هذا الدليل النمط عملياً على فاحصات الأسهم وملفات SEC EDGAR وبيانات السوق المحمية بـ Turnstile، بأمثلة Python جاهزة للتشغيل.
أين تظهر اختبارات CAPTCHA في المواقع المالية
يوضح الجدول التالي أين تصطدم عمليات الجمع بالتحقق ونوع كل اختبار على أبرز المنصات:
| المصدر | نوع الاختبار | ما الذي يشغّله | قيمة البيانات |
|---|---|---|---|
| SEC EDGAR | reCAPTCHA v2 | الطلبات كبيرة الحجم | ملفات الشركات |
| Yahoo Finance | reCAPTCHA v2 | رصد عمليات الجمع | أسعار الأسهم والسجل التاريخي |
| Bloomberg | Cloudflare Turnstile | أي وصول آلي | بيانات السوق |
| Finviz | reCAPTCHA v2 | الدخول إلى فاحص الأسهم | نتائج الفرز |
| TradingView | Cloudflare Challenge | تحديد معدل الطلبات | الرسوم والمؤشرات |
| Morningstar | reCAPTCHA v3 | صفحات تصدير البيانات | تحليلات الصناديق |
سيناريو تطبيقي من السوق الإقليمي
تخيّل فريق بيانات في شركة إدارة أصول بالخليج يبني لوحة متابعة يومية تجمع أسعار الأسهم الأمريكية من فاحصات عامة وملفات SEC EDGAR لعملاء إقليميين يستثمرون في الأسواق العالمية. مع تشغيل السكربت خلال ساعات السوق الأمريكية، تبدأ المواقع بعرض reCAPTCHA وTurnstile بعد عشرات الطلبات. وبدل إيقاف الجمع أو التدخل اليدوي، يمرّر الفريق كل اختبار عبر CaptchaAI ويستأنف الطلب تلقائياً — فتبقى اللوحة محدّثة دون إشراف بشري متواصل.
قلّل ظهور الاختبارات بضبط إيقاع الطلبات
المواقع المالية أكثر صرامة تجاه الوصول الآلي من معظم المواقع، لذا تبدأ المعالجة الذكية قبل كتابة أي كود حل: الإيقاع المنضبط يقلّل ظهور الاختبارات من الأساس ويحافظ على استقرار الجلسة. ركّز على ثلاثة مبادئ:
- باعد بين الطلبات، ولا تفتح اتصالات متزامنة كثيرة على النطاق نفسه.
- ثبّت هوية الجلسة — وكيل مستخدم واقعي وبروكسي سكني — طوال مدة الجمع.
- اجمع خارج أوقات الذروة، وضمّن بريد جهة الاتصال في وكيل المستخدم على SEC EDGAR.
| الإجراء | التوصية |
|---|---|
| تأخير بين الطلبات | 2–5 ثوانٍ بين الصفحات |
| الاتصالات المتزامنة | 3–5 كحد أقصى لكل نطاق |
| نوع البروكسي | سكني أو من مزوّد خدمة الإنترنت (ISP) |
| مدة الجلسة | جلسات ثابتة من 5–10 دقائق |
| وكيل المستخدم | واقعي وثابت طوال الجلسة |
| SEC EDGAR | تضمين بريد جهة الاتصال في وكيل المستخدم (مطلوب) |
| ساعات السوق | الجمع خارج أوقات الذروة قدر الإمكان |
جمع نتائج فاحص الأسهم
النمط الأساسي واحد: أرسل مفتاح الموقع، استطلع النتيجة، ثم أعد إرسال الطلب ومعه الرمز في الحقل g-recaptcha-response. الدالة solve_captcha والصنف FinancialScraper أدناه يشكّلان الأساس الذي تعيد بقية الأمثلة استخدامه:
import requests
import time
from bs4 import BeautifulSoup
import re
CAPTCHAAI_KEY = "YOUR_API_KEY"
CAPTCHAAI_URL = "https://ocr.captchaai.com"
def solve_captcha(method, sitekey, pageurl, **kwargs):
data = {
"key": CAPTCHAAI_KEY,
"method": method,
"googlekey": sitekey,
"pageurl": pageurl,
"json": 1,
}
data.update(kwargs)
resp = requests.post(f"{CAPTCHAAI_URL}/in.php", data=data)
task_id = resp.json()["request"]
for _ in range(60):
time.sleep(5)
result = requests.get(f"{CAPTCHAAI_URL}/res.php", params={
"key": CAPTCHAAI_KEY, "action": "get",
"id": task_id, "json": 1,
})
r = result.json()
if r["request"] != "CAPCHA_NOT_READY":
return r["request"]
raise TimeoutError("Solve timeout")
class FinancialScraper:
def __init__(self, proxy=None):
self.session = requests.Session()
if proxy:
self.session.proxies = {"http": proxy, "https": proxy}
self.session.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 Chrome/126.0.0.0 Safari/537.36",
"Accept-Language": "en-US,en;q=0.9",
})
def scrape_screener(self, url):
"""Scrape stock screener, handling CAPTCHA if triggered."""
resp = self.session.get(url, timeout=30)
# Check for CAPTCHA
sitekey_match = re.search(r'data-sitekey="([^"]+)"', resp.text)
if sitekey_match:
sitekey = sitekey_match.group(1)
token = solve_captcha("userrecaptcha", sitekey, url)
# Resubmit with token
resp = self.session.post(url, data={
"g-recaptcha-response": token,
})
return self._parse_stocks(resp.text)
def _parse_stocks(self, html):
soup = BeautifulSoup(html, "html.parser")
stocks = []
for row in soup.select("table.screener-table tr")[1:]:
cols = row.select("td")
if len(cols) >= 8:
stocks.append({
"ticker": cols[1].get_text(strip=True),
"company": cols[2].get_text(strip=True),
"sector": cols[3].get_text(strip=True),
"price": cols[6].get_text(strip=True),
"change": cols[7].get_text(strip=True),
})
return stocks
# Usage
scraper = FinancialScraper(
proxy="http://user:pass@residential.proxy.com:5000"
)
stocks = scraper.scrape_screener("https://screener.example.com/screener.ashx?v=111")
for stock in stocks[:5]:
print(f"{stock['ticker']}: {stock['price']} ({stock['change']})")
استخراج ملفات SEC EDGAR
تفرض SEC EDGAR قيدين يجب مراعاتهما معاً في الكود:
- حدّ على معدل الطلبات، مع عرض اختبار CAPTCHA عند الوصول كبير الحجم.
- اشتراط وكيل مستخدم يحمل بريد جهة اتصال، وإلا رُفض الطلب بالرمز 403.
الصنف التالي يعالج الحالتين معاً:
import json
class SECFilingScraper:
BASE_URL = "https://efts.sec.gov/LATEST"
def __init__(self, user_agent_email, proxy=None):
self.session = requests.Session()
if proxy:
self.session.proxies = {"http": proxy, "https": proxy}
# SEC requires identifying User-Agent
self.session.headers.update({
"User-Agent": f"CompanyName admin@{user_agent_email}",
"Accept": "application/json",
})
def search_filings(self, company, filing_type="10-K"):
"""Search EDGAR for specific filing types."""
url = f"{self.BASE_URL}/search-index"
params = {
"q": company,
"dateRange": "custom",
"forms": filing_type,
}
resp = self.session.get(url, params=params, timeout=30)
# Handle CAPTCHA if triggered
if "captcha" in resp.text.lower() or resp.status_code == 403:
sitekey = self._extract_sitekey(resp.text)
if sitekey:
token = solve_captcha("userrecaptcha", sitekey, url)
resp = self.session.post(url, data={
**params,
"g-recaptcha-response": token,
})
return resp.json() if resp.status_code == 200 else {}
def download_filing(self, filing_url):
"""Download individual filing document."""
resp = self.session.get(filing_url, timeout=60)
if resp.status_code == 200:
return resp.text
return None
def _extract_sitekey(self, html):
match = re.search(r'data-sitekey="([^"]+)"', html)
return match.group(1) if match else None
# Usage
sec = SECFilingScraper(
user_agent_email="example.com",
proxy="http://user:pass@proxy.example.com:5000",
)
filings = sec.search_filings("Apple Inc", "10-K")
بيانات السوق المحمية بـ Cloudflare Turnstile
يبقى منطق أرسل/استطلع/استخدم الرمز كما هو، ولا يتغيّر سوى شيئين عند الانتقال إلى مواقع محمية بـ Turnstile:
- اسم الطريقة يصبح
turnstileبدلuserrecaptcha. - حقل الرمز في إعادة الإرسال يصبح
cf-turnstile-responseبدلg-recaptcha-response.
يظهر ذلك في الدالة التالية:
def scrape_turnstile_market_data(url, sitekey):
"""Handle Cloudflare Turnstile on financial data sites."""
token = solve_captcha("turnstile", sitekey, url)
session = requests.Session()
session.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 Chrome/126.0.0.0 Safari/537.36",
})
resp = session.post(url, data={
"cf-turnstile-response": token,
}, timeout=30)
return resp.json() if resp.status_code == 200 else None
لقطة يومية مجدولة لبيانات السوق
بعد أن يصبح التعامل مع الاختبار جزءاً من الصنف، يتحوّل الجمع اليومي إلى حلقة بسيطة تمرّ على الرموز وتحفظ النتائج في ملف CSV، مع تأخير قصير بين الطلبات:
import csv
from datetime import datetime
def daily_market_snapshot(tickers, output_dir="data"):
"""Collect daily stock data, handling CAPTCHAs automatically."""
scraper = FinancialScraper(
proxy="http://user:pass@residential.proxy.com:5000"
)
date_str = datetime.now().strftime("%Y-%m-%d")
results = []
for ticker in tickers:
url = f"https://screener.example.com/quote.ashx?t={ticker}"
try:
data = scraper.scrape_screener(url)
if data:
results.extend(data)
time.sleep(2) # Rate limit
except Exception as e:
print(f"Error on {ticker}: {e}")
# Save to CSV
filepath = f"{output_dir}/market_{date_str}.csv"
with open(filepath, "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=["ticker", "company", "sector", "price", "change"])
writer.writeheader()
writer.writerows(results)
print(f"Saved {len(results)} records to {filepath}")
return results
# Run daily
tickers = ["AAPL", "GOOGL", "MSFT", "AMZN", "TSLA"]
daily_market_snapshot(tickers)
حلّ المشكلات الشائعة
| المشكلة | السبب | الحل |
|---|---|---|
| خطأ 403 على SEC EDGAR | وكيل المستخدم بلا بريد إلكتروني | أضف ترويسة CompanyName email@domain |
| ظهور CAPTCHA في كل طلب | تجاوز حد معدل الطلبات | أضف تأخيراً 3–5 ثوانٍ بين الطلبات |
| أسعار قديمة غير محدّثة | استجابة مخزّنة مؤقتاً | أضف معامل استعلام لكسر التخزين المؤقت |
| فشل تحليل JSON | إرجاع صفحة CAPTCHA بدل البيانات | تحقق من وجود CAPTCHA قبل التحليل |
| حظر عنوان IP | طلبات كثيرة من العنوان نفسه | بدّل إلى بروكسي سكني دوّار |
أسئلة شائعة
ما نوع البروكسي الأنسب لمواقع البيانات المالية؟
استخدم بروكسي سكنياً أو من مزوّد خدمة إنترنت (ISP) مع تدوير للعناوين وجلسات ثابتة قصيرة. تُكتشف بروكسيات مراكز البيانات بسرعة على المنصات المالية، ما يرفع تكرار ظهور CAPTCHA ويؤدي إلى حظر العناوين.
كيف أتعامل مع ظهور CAPTCHA أثناء جلسة جمع جارية؟
لا توقف السكربت: استخرج مفتاح الموقع من الصفحة، أرسله إلى CaptchaAI عبر الدالة solve_captcha، ثم أعد إرسال الطلب نفسه مضيفاً الرمز في g-recaptcha-response أو cf-turnstile-response. أما إذا تكرر الاختبار في كل طلب، فالسبب غالباً تجاوز حد المعدل — عندها زد التأخير بين الطلبات.
هل يتعامل CaptchaAI مع reCAPTCHA v3 وCloudflare معاً؟
نعم، يحل CaptchaAI اختبارات reCAPTCHA v2 وv3 وCloudflare Turnstile وCloudflare Challenge، وهي الأنواع الأكثر شيوعاً على مواقع البيانات المالية. يتغيّر اسم الطريقة (method) حسب النوع فقط، بينما يبقى نمط أرسل/استطلع/استخدم الرمز ثابتاً في كل الحالات.
كم تكلفة تشغيل عملية جمع يومية كبيرة الحجم؟
يعتمد تسعير CaptchaAI على عدد الـ Threads المتزامنة لا على عدد عمليات الحل، مع حلول غير محدودة لكل Thread خلال الشهر. تبدأ خطة BASIC من 15$ شهرياً (5 threads)، وترتفع سعة المعالجة المتزامنة في الخطط الأعلى مثل ADVANCE بسعر 90$ شهرياً (50 threads) — ما يجعل تكلفة الجمع اليومي ثابتة ومتوقعة.
أدلة ذات صلة
جمّع بياناتك المالية دون أن يوقفك اختبار CAPTCHA — احصل على مفتاح CaptchaAI وأتمِت أبحاث السوق.