Сценарии использования

Парсинг финансовых данных с обработкой CAPTCHA

Финансовые платформы, такие как программы проверки акций, SEC EDGAR и торговые платформы, защищают данные с помощью CAPTCHA, чтобы предотвратить автоматическое извлечение. CaptchaAI решает эти проблемы программно, поэтому вы можете собирать рыночные данные в большом масштабе.


Где появляются CAPTCHA в финансах

Источник Тип капчи Курок Значение данных
ТРЦ ЭДГАР reCAPTCHA v2 Большой объем запросов Документы компании
Yahoo Финансы reCAPTCHA v2 Обнаружение парсинга Котировки акций, история
Блумберг Cloudflare Turnstile Весь автоматический доступ Рыночные данные
Финвиз reCAPTCHA v2 Доступ к скринеру акций Результаты скрининга
ТрейдингВью страница Cloudflare-защиты в staging Ограничение скорости Графики, индикаторы
Морнингстар reCAPTCHA v3 Страницы экспорта данных Аналитика фонда

Скрининг акций

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 для доступа к большим объемам:

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")

Рыночные данные по турникетам, защищенным турникетами

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

Запланированный сбор данных

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)

подходящий практики ограничения скорости

Финансовые сайты более строги в отношении автоматического доступа:

Упражняться Рекомендация
Запросить отсрочку 2-5 секунд между страницами
Параллельные соединения Макс. 3–5 на домен
Тип прокси Жилой или интернет-провайдер
Продолжительность сеанса Закрепленные сеансы по 5–10 минут
Пользовательский агент Реалистичный, последовательный за сеанс
ТРЦ ЭДГАР Включить контактный адрес электронной почты в UA (обязательно)
Часы работы рынка Очистка в непиковое время, когда это возможно

Поиск неисправностей

Проблема Причина Исправить
403 на ТРЦ ЭДГАР Отсутствует пользовательский агент с электронной почтой Добавьте заголовок CompanyName email@domain
CAPTCHA на каждый запрос Превышен лимит скорости Добавьте задержки в 3–5 секунд между запросами.
Устаревшие данные о ценах Кэшированный ответ Добавить параметр запроса на очистку кеша
Ошибка анализа JSON Вместо этого возвращена страница CAPTCHA Проверьте CAPTCHA перед парсингом
IP заблокирован Слишком много запросов с одного IP Переключиться на ротационный авторизованный сетевой выход

Часто задаваемые вопросы

Законно ли сбор финансовых данных?

Публичные финансовые данные (отчеты SEC, котировки акций), как правило, допустимы. Всегда соблюдайте условия обслуживания и ограничения тарифов. SEC EDGAR явно предоставляет доступ к EDGAR для исследовательских целей.

Почему финансовые сайты используют CAPTCHA?

Чтобы предотвратить крупномасштабное автоматическое извлечение, которое может привести к манипулированию рынком, сбору конкурентной информации или чрезмерной нагрузке на сервер.

Как часто мне следует собирать рыночные данные?

Для цен на акции: максимум один раз в минуту в часы работы рынка. Для подачи документов: обычно один раз в день. Чрезмерное сканирование активирует CAPTCHA быстрее.


Связанные руководства

  • Качество прокси влияет на скорость решения
  • Ротация авторизованный сетевой выход

  • Собирайте финансовые данные без прерываний CAPTCHA —получите ключ CaptchaAIи автоматизировать исследование рынка.*
Комментарии для этой статьи отключены.