Casos de Uso

Coleta de dados de saúde atrás das paredes do CAPTCHA

Os portais de dados de saúde – diretórios de fornecedores, bancos de dados de preços de medicamentos e registros de ensaios clínicos – usam CAPTCHAs para evitar a coleta automatizada de dados. Os investigadores e as plataformas de tecnologia da saúde precisam destes dados para análise, conformidade e tomada de decisões informadas.


Onde os CAPTCHAs aparecem

Fonte Tipo CAPTCHA Dados Caso de uso
Diretórios de provedores (NPI) Imagem CAPTCHA Pesquisa Doctor/facility Adequação da rede
Portais de preços de medicamentos reCAPTCHA v2 Preços de medicamentos Transparência de preços
Registros de ensaios clínicos reCAPTCHA v2 Dados do ensaio, resultados Análise de pesquisa
Formulários de seguros reCAPTCHA v2 Listas de cobertura de medicamentos Comparação de formulário
Conselhos de licenciamento estaduais Imagem CAPTCHA Verificação de licença Verificações de credenciais
Classificações de qualidade hospitalar Cloudflare Turnstile Métricas de qualidade Análise de desempenho

Raspador de diretório de provedor

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

Coleta de dados de ensaios clínicos

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

Considerações sobre privacidade de dados

Tipo de dados Sensibilidade Recomendação
Diretórios de provedores Baixo (informações públicas) Geralmente seguro para coletar
Preços de medicamentos Baixo (preço público) Permitido para transparência
Metadados de ensaios clínicos Baixo (registros públicos) Uso de pesquisa apropriado
Avaliações de pacientes Médio Anonimizar antes da análise
Detalhes do plano de seguro Baixo (taxas publicadas) Permitido para comparação

Importante: Nunca tente coletar informações de saúde protegidas (PHI). Concentre-se apenas em dados publicamente disponíveis e não específicos do paciente.


Solução de problemas

Problema Causa Correção
Imagem CAPTCHA ilegível Imagem de baixa qualidade Tentar novamente – nova imagem gerada
A pesquisa do provedor retorna vazia CAPTCHA bloqueou a pesquisa Resolva o CAPTCHA antes de enviar
O preço dos medicamentos varia de acordo com o local Preços baseados em localização geográfica Combine a localização do proxy com o CEP
A sessão expira em várias páginas Tempo limite do portal Conclua pesquisas rapidamente
Taxa limitada em pesquisas em lote Muitos pedidos Adicione atrasos de 5 a 10 segundos

Perguntas frequentes

A coleta de dados sobre preços de saúde é permitida?

A transparência dos preços dos medicamentos é incentivada pela regulamentação (Regra de Transparência de Preços do CMS). Os dados do diretório de provedores públicos são geralmente acessíveis.

Posso comparar os preços dos medicamentos nas farmácias?

Sim. Serviços como GoodRx fazem isso em grande escala. CaptchaAI lida com os CAPTCHAs que os portais de preços usam para limitar o acesso automatizado.

Como lidar com a HIPAA ao coletar sites de saúde?

A HIPAA se aplica a informações de saúde protegidas (PHI). Dados públicos como diretórios de fornecedores, preços de medicamentos e registros de ensaios clínicos não são PHI. Nunca raspe registros individuais de pacientes.


Guias Relacionados


Colete dados de saúde com eficiência -obtenha sua chave CaptchaAIe automatizar pesquisas de fornecedores e preços.

Os comentários estão desativados para este artigo.