You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

网页爬取如何定位表单元素?bs4无法识别表单解决方案

israeldrugs.health.gov.il 药品查询页爬取方案

问题根因

你用bs4找不到表单是必然结果:该站点是AngularJS构建的单页应用,所有DOM元素(搜索表单、输入框、按钮、查询结果)全部由前端JavaScript在客户端动态渲染生成。bs4只能解析服务器初始返回的静态HTML,这部分静态内容里只有Angular的脚本挂载占位节点,不存在任何实际业务元素,和你选择器写法是否正确没有关系。
之前的同类解答失效,是因为站点后续迭代调整了接口路径、DOM属性规则,旧方案的选择器、请求地址已经和当前站点逻辑不匹配。

方案1:直接调用后端接口(优先选择,效率最高)

不需要加载浏览器资源,爬取速度是渲染方案的10倍以上,适合批量查询场景

  • 打开浏览器开发者工具的Network面板,筛选Fetch/XHR类型请求,手动在页面触发一次查询就能抓到核心查询接口,请求逻辑非常简单:
    • 接口地址:https://israeldrugs.health.gov.il/IdServer/api/Drugs/GetDrugsBy
    • 请求方法:POST
    • 请求格式:JSON
    • 核心参数:drugName字段传入你要搜索的关键词,page、pageSize字段控制分页
  • 请求必须携带正确的Referer、Content-Type头,否则会被站点拦截,参考实现代码:
import requests

req_headers = {
    "Accept": "application/json, text/plain, */*",
    "Content-Type": "application/json;charset=UTF-8",
    "Referer": "https://israeldrugs.health.gov.il/",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36"
}
search_payload = {
    "drugName": "输入你要查询的药品关键词",
    "page": 1,
    "pageSize": 20,
    # 其余固定参数可以直接从浏览器抓到的请求体里复制,不需要修改
}
resp = requests.post(
    "https://israeldrugs.health.gov.il/IdServer/api/Drugs/GetDrugsBy",
    headers=req_headers,
    json=search_payload
)
# 接口直接返回结构化JSON数据,不需要做HTML解析
result_data = resp.json()
print(result_data)

方案2:浏览器自动化渲染(接口逆向难度大时使用)

兼容性最强,不需要关心接口签名、参数加密逻辑,完全模拟真人操作

  • 放弃requests + bs4的静态爬取组合,使用支持JS渲染的工具:
    • 轻量场景可以选requests-html,代码量小
    • 稳定长期使用选Playwright,自动匹配浏览器驱动,等待API封装完善
  • 核心注意点:必须加显式等待,等目标元素完全渲染到DOM树之后再执行输入、点击操作,不要页面刚加载就去定位元素,参考Playwright实现代码:
from playwright.sync_api import sync_playwright

with sync_playwright() as pw:
    # headless=True可以后台静默运行,不需要弹出浏览器窗口
    browser = pw.chromium.launch(headless=True)
    page = browser.new_page()
    page.goto("https://israeldrugs.health.gov.il/#!/byDrug", wait_until="networkidle")
    
    # 定位搜索输入框,输入关键词
    search_input = page.wait_for_selector("input[ng-model='search.drugName']", timeout=15000)
    search_input.fill("输入你要查询的药品关键词")
    
    # 点击左侧蓝色查询按钮
    page.click("button[ng-click='searchDrugs()']")
    
    # 等待查询结果加载完成后提取内容
    page.wait_for_selector(".result-item", timeout=10000)
    all_results = [item.inner_text() for item in page.locator(".result-item").all()]
    print(all_results)
    
    browser.close()

注意事项

  • 爬取时控制请求频率,单IP请求间隔建议不低于2秒,避免被站点封禁
  • 如果后续接口新增签名校验,优先检查Network面板里的请求头、请求体新增字段,更新参数即可,不需要直接切换到浏览器渲染方案

内容的提问来源于stack exchange,提问作者gtomer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 23:36:21