Trường Hợp Sử Dụng

Thu thập dữ liệu chăm sóc sức khỏe đằng sau bức tường CAPTCHA

Danh mục bác sĩ NPI, giá thuốc và thử nghiệm lâm sàng tại Mỹ đều là dữ liệu công khai — nhưng gần như cổng nào cũng cắm reCAPTCHA v2 hoặc CAPTCHA hình ảnh trước khi cho xem kết quả. Đội outsourcing hay startup health-tech tại Việt Nam dựng dashboard cho khách hàng Mỹ sẽ gặp điểm nghẽn này mỗi khi cổng đổi giao diện. Ba nhóm cổng hay gặp nhất:

  • Danh mục nhà cung cấp & hội đồng cấp phép — CAPTCHA hình ảnh
  • Giá thuốc & công thức bảo hiểm — reCAPTCHA v2
  • Thử nghiệm lâm sàng & xếp hạng bệnh viện — reCAPTCHA v2, Turnstile

CAPTCHA xuất hiện ở những cổng thông tin y tế nào

Sáu nhóm cổng phổ biến nhất:

Nguồn Loại CAPTCHA Dữ liệu Trường hợp sử dụng
Danh mục nhà cung cấp (NPI) CAPTCHA hình ảnh Tra cứu bác sĩ/cơ sở y tế Đánh giá độ phủ mạng lưới
Cổng giá thuốc reCAPTCHA v2 Giá thuốc Minh bạch về giá
Sổ đăng ký thử nghiệm lâm sàng reCAPTCHA v2 Dữ liệu thử nghiệm, kết quả Phân tích nghiên cứu
Công thức bảo hiểm reCAPTCHA v2 Danh sách bảo hiểm thuốc So sánh gói bảo hiểm
Hội đồng cấp phép nhà nước CAPTCHA hình ảnh Xác minh giấy phép Kiểm tra thông tin xác thực
Đánh giá chất lượng bệnh viện Cloudflare Turnstile Số liệu chất lượng Phân tích hiệu suất

Dữ liệu y tế nào được phép thu thập

  • Danh mục nhà cung cấp — độ nhạy thấp (công khai), an toàn để thu thập.
  • Giá thuốc — độ nhạy thấp (giá công khai), được phép vì mục đích minh bạch.
  • Siêu dữ liệu thử nghiệm lâm sàng — độ nhạy thấp (đăng ký công cộng), phù hợp cho nghiên cứu.
  • Đánh giá của bệnh nhân — độ nhạy trung bình, cần ẩn danh trước khi phân tích.
  • Chi tiết gói bảo hiểm — độ nhạy thấp (tỷ lệ công bố), được phép so sánh.

Đừng bao giờ thu thập thông tin sức khỏe được bảo vệ (PHI); chỉ dùng dữ liệu công khai, không gắn bệnh nhân cụ thể.

Đội tại Việt Nam phục vụ khách hàng Mỹ nên ghi log nguồn dữ liệu theo tinh thần Nghị định 13/2023/NĐ-CP, dù dữ liệu không phải PHI.


Script quét danh mục nhà cung cấp bằng Python

Xử lý cả hai loại CAPTCHA trên cùng một script

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:[email protected]: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",
)

batch_provider_lookup gộp nhiều chuyên khoa và địa điểm rồi xuất thẳng ra CSV.


Thu thập dữ liệu thử nghiệm lâm sàng qua reCAPTCHA v2

Giải token một lần rồi gửi kèm điều kiện tìm kiếm

def collect_clinical_trials(search_url, condition, sitekey):
    """Collect clinical trial data for a medical condition."""
    collector = HealthcareDataCollector(
        proxy="http://user:[email protected]: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

Xử lý lỗi thường gặp khi thu thập dữ liệu y tế

Lỗi hay gặp khi chạy script ở trên:

Vấn đề Nguyên nhân Cách xử lý
Hình ảnh CAPTCHA không đọc được Ảnh chất lượng thấp Thử lại — ảnh mới sẽ được tạo
Tìm kiếm nhà cung cấp trả về rỗng CAPTCHA đã chặn request Giải CAPTCHA trước khi gửi form
Giá thuốc thay đổi theo địa điểm Định giá theo vị trí địa lý Khớp proxy với mã zip đang tra cứu
Phiên hết hạn khi lướt nhiều trang Cổng thông tin timeout Hoàn thành tìm kiếm nhanh
Bị giới hạn tần suất khi tra cứu hàng loạt Gửi quá nhiều request liên tiếp Thêm độ trễ 5–10 giây giữa các lần gọi

Câu hỏi thường gặp về thu thập dữ liệu y tế qua CAPTCHA

Danh mục bác sĩ NPI và giá thuốc có phải dữ liệu được phép thu thập không?

Có. Quy tắc minh bạch giá thuốc của CMS khuyến khích công bố giá; danh mục NPI vốn để tra cứu công khai — miễn không đụng hồ sơ bệnh nhân cá nhân.

CaptchaAI xử lý CAPTCHA hình ảnh trên danh mục NPI như thế nào?

Gửi ảnh dạng base64 tới in.php, sau đó polling res.php để lấy kết quả — luồng xử lý giống hệt reCAPTCHA v2, chỉ khác tham số method.

Có cần khớp proxy theo từng bang khi tra cứu giá thuốc không?

Nên có, nếu cổng trả giá theo vùng địa lý — nhiều cổng giá thuốc Mỹ định giá theo IP hoặc mã zip.

Thu thập dữ liệu y tế công khai có vi phạm HIPAA hay Nghị định 13/2023/NĐ-CP không?

Không, nếu dữ liệu công khai và không gắn bệnh nhân cụ thể. HIPAA chỉ điều chỉnh PHI; đội tại Việt Nam vẫn nên ghi log nguồn dữ liệu theo tinh thần Nghị định 13/2023/NĐ-CP.


Hướng dẫn liên quan


Bắt đầu ngay

Đừng để CAPTCHA làm chậm pipeline dữ liệu y tế của bạn — lấy API key CaptchaAI và chạy thử script trong bài ngay hôm nay.

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