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

Сбор медицинских данных за стенами CAPTCHA

Порталы медицинских данных — каталоги поставщиков, базы данных цен на лекарства и реестры клинических исследований — используют CAPTCHA для предотвращения автоматического сбора данных. Эти данные нужны исследователям и платформам медицинских технологий для анализа, соблюдения требований и принятия обоснованных решений.


Где появляются CAPTCHA

Источник Тип капчи Данные Вариант использования
Справочники поставщиков (NPI) Капча изображения Поиск доктора/facility Адекватность сети
Порталы цен на лекарства reCAPTCHA v2 Цены на лекарства Прозрачность цен
Реестры клинических исследований reCAPTCHA v2 Данные испытаний, результаты Анализ исследований
Страховые формуляры reCAPTCHA v2 Списки покрытия лекарств Формулярное сравнение
Государственные лицензионные комиссии Капча изображения Проверка лицензии Проверка учетных данных
Рейтинги качества больниц Cloudflare Turnstile Показатели качества Анализ производительности

Парсер каталогов поставщиков

import requests
import time
import re
import base64
from bs4 import BeautifulSoup
import csv

CAPTCHAAI_KEY = "YOUR_API_KEY"
CAPTCHAAI_URL = "https://ocr.captchaai.com"


def solve_recaptcha(sitekey, pageurl):
    resp = requests.post(f"{CAPTCHAAI_URL}/in.php", data={
        "key": CAPTCHAAI_KEY, "method": "userrecaptcha",
        "googlekey": sitekey, "pageurl": pageurl, "json": 1,
    })
    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,
        })
        data = result.json()
        if data["request"] != "CAPCHA_NOT_READY":
            return data["request"]
    raise TimeoutError("Timeout")


def solve_image_captcha(image_bytes):
    img_b64 = base64.b64encode(image_bytes).decode()
    resp = requests.post(f"{CAPTCHAAI_URL}/in.php", data={
        "key": CAPTCHAAI_KEY, "method": "base64",
        "body": img_b64, "json": 1,
    })
    task_id = resp.json()["request"]
    for _ in range(20):
        time.sleep(3)
        result = requests.get(f"{CAPTCHAAI_URL}/res.php", params={
            "key": CAPTCHAAI_KEY, "action": "get",
            "id": task_id, "json": 1,
        })
        data = result.json()
        if data["request"] != "CAPCHA_NOT_READY":
            return data["request"]
    raise TimeoutError("Timeout")


class HealthcareDataCollector:
    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",
        })

    def search_providers(self, portal_url, specialty, location, sitekey=None):
        """Search provider directory with CAPTCHA handling."""
        resp = self.session.get(portal_url, timeout=30)

        data = {"specialty": specialty, "location": location}

        # Handle CAPTCHA
        if sitekey:
            token = solve_recaptcha(sitekey, portal_url)
            data["g-recaptcha-response"] = token
        else:
            captcha_img = re.search(r'src="(/captcha[^"]+)"', resp.text)
            if captcha_img:
                img_url = portal_url.rstrip("/") + captcha_img.group(1)
                img = self.session.get(img_url)
                data["captcha"] = solve_image_captcha(img.content)

        resp = self.session.post(portal_url, data=data)
        return self._parse_providers(resp.text)

    def lookup_drug_prices(self, pricing_url, drug_name, zip_code, sitekey):
        """Look up drug prices with CAPTCHA solving."""
        # Load search page
        self.session.get(pricing_url)

        # Solve CAPTCHA
        token = solve_recaptcha(sitekey, pricing_url)

        resp = self.session.post(pricing_url, data={
            "drug": drug_name,
            "zip": zip_code,
            "g-recaptcha-response": token,
        })

        if resp.status_code == 200:
            return self._parse_prices(resp.text)
        return []

    def batch_provider_lookup(self, portal_url, specialties, locations, output_file):
        """Batch search across specialties and locations."""
        all_providers = []

        for specialty in specialties:
            for location in locations:
                try:
                    providers = self.search_providers(
                        portal_url, specialty, location,
                    )
                    for p in providers:
                        p["specialty_search"] = specialty
                        p["location_search"] = location
                    all_providers.extend(providers)
                    print(f"{specialty} / {location}: {len(providers)} providers")
                    time.sleep(5)
                except Exception as e:
                    print(f"Error: {specialty} / {location}: {e}")

        # Export
        if all_providers:
            keys = all_providers[0].keys()
            with open(output_file, "w", newline="", encoding="utf-8") as f:
                writer = csv.DictWriter(f, fieldnames=keys)
                writer.writeheader()
                writer.writerows(all_providers)

        return all_providers

    def _parse_providers(self, html):
        soup = BeautifulSoup(html, "html.parser")
        providers = []
        for card in soup.select(".provider-card, .doctor-result, tr.provider"):
            providers.append({
                "name": self._text(card, ".name, .provider-name"),
                "specialty": self._text(card, ".specialty"),
                "address": self._text(card, ".address"),
                "phone": self._text(card, ".phone"),
                "accepting": self._text(card, ".accepting-patients"),
            })
        return providers

    def _parse_prices(self, html):
        soup = BeautifulSoup(html, "html.parser")
        prices = []
        for row in soup.select(".pharmacy-row, .price-result"):
            prices.append({
                "pharmacy": self._text(row, ".pharmacy-name"),
                "price": self._text(row, ".price, .drug-price"),
                "quantity": self._text(row, ".quantity"),
            })
        return prices

    def _text(self, el, selector):
        found = el.select_one(selector)
        return found.get_text(strip=True) if found else ""


# Usage
collector = HealthcareDataCollector(
    proxy="http://user:pass@residential.proxy.com:5000"
)

# Provider search
providers = collector.search_providers(
    portal_url="https://provider-directory.example.com/search",
    specialty="Cardiology",
    location="New York, NY",
)

# Drug pricing
prices = collector.lookup_drug_prices(
    pricing_url="https://drug-prices.example.com/compare",
    drug_name="atorvastatin",
    zip_code="10001",
    sitekey="6Lc_xxxxxxx",
)

Сбор данных клинических исследований

def collect_clinical_trials(search_url, condition, sitekey):
    """Collect clinical trial data for a medical condition."""
    collector = HealthcareDataCollector(
        proxy="http://user:pass@residential.proxy.com:5000"
    )

    token = solve_recaptcha(sitekey, search_url)
    resp = collector.session.post(search_url, data={
        "condition": condition,
        "status": "recruiting",
        "g-recaptcha-response": token,
    })

    if resp.status_code != 200:
        return []

    soup = BeautifulSoup(resp.text, "html.parser")
    trials = []
    for item in soup.select(".trial-item, .study-result"):
        trials.append({
            "title": collector._text(item, ".title, h3"),
            "status": collector._text(item, ".status"),
            "sponsor": collector._text(item, ".sponsor"),
            "phase": collector._text(item, ".phase"),
            "enrollment": collector._text(item, ".enrollment"),
            "location": collector._text(item, ".location"),
        })

    return trials

Вопросы конфиденциальности данных

Тип данных Чувствительность Рекомендация
Каталоги поставщиков Низкий (публичная информация) В целом безопасно собирать
Цены на лекарства Низкий (публичные цены) Разрешено для прозрачности
Метаданные клинического исследования Низкий (государственные реестры) Исследовательское использование целесообразно
Отзывы пациентов Середина Анонимизировать перед анализом
Детали страхового плана Низкий (опубликованные ставки) Разрешено для сравнения

Важно! Никогда не пытайтесь собирать защищенную медицинскую информацию (PHI). Сосредоточьтесь только на общедоступных, не относящихся к конкретному пациенту данных.


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

Проблема Причина Исправить
Изображение CAPTCHA не читается Изображение низкого качества Повторить попытку — создано новое изображение.
Поиск поставщика возвращает пустой результат CAPTCHA заблокировала поиск Решите CAPTCHA перед отправкой
Цена на препарат варьируется в зависимости от местоположения Географическое ценообразование Сопоставьте местоположение прокси с почтовым индексом
Сессия истекает на многостраничной странице Тайм-аут портала Выполняйте поиск быстро
Ограничение скорости при пакетном поиске Слишком много запросов Добавьте задержки на 5–10 секунд.

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

Разрешен ли сбор данных о ценах на здравоохранение?

Прозрачность цен на лекарства поощряется регулированием (Правило прозрачности цен CMS). Данные каталога общедоступных поставщиков обычно доступны.

Могу ли я сравнить цены на лекарства в разных аптеках?

Да. Такие сервисы, как GoodRx, делают это в больших масштабах. CaptchaAI обрабатывает CAPTCHA, которые порталы ценообразования используют для ограничения автоматического доступа.

Как обращаться с HIPAA при парсинге сайтов здравоохранения?

HIPAA применяется к защищенной медицинской информации (PHI). Публичные данные, такие как каталоги поставщиков услуг, цены на лекарства и реестры клинических исследований, не являются закрытой медицинской информацией. Никогда не удаляйте отдельные записи пациентов.


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

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

Эффективный сбор медицинских данных —получите ключ CaptchaAIи автоматизировать поиск поставщиков и цен.

Комментарии для этой статьи отключены.