You need to enable JavaScript to run this app. 使用requests爬取网页表格名称时,如何实现后续分页数据的持续提取?
优惠活动
大模型
产品
解决方案
定价
更多

使用requests爬取网页表格名称时,如何实现后续分页数据的持续提取?

站点分页爬取的实现方案

该站点为ASP.NET WebForm 回发驱动架构,所有分页操作无独立URL,完全依靠携带动态防伪字段的POST请求完成跳转,无法通过修改URL参数直接访问分页内容。

核心实现逻辑

  • 所有请求必须携带从上个响应中提取的最新__VIEWSTATE、__EVENTVALIDATION、__VIEWSTATEGENERATOR动态字段,这组字段是服务器校验请求合法性的核心标识,固定复用初始值会被拦截
  • 分页请求不需要再携带提交搜索的Start Search按钮参数,需通过专属的回发字段告知服务器本次操作为点击“下一页”按钮
  • 循环终止条件:解析当前页HTML时,未检测到可点击的“下一页”元素,即代表到达最后一页,退出循环

完整修改后代码

import requests
from bs4 import BeautifulSoup

link = 'https://hsapps.azdhs.gov/ls/sod/SearchProv.aspx?type=DD'

with requests.Session() as s:
    s.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
    
    # 初始GET请求,获取页面基础防伪字段
    r = s.get(link)
    soup = BeautifulSoup(r.text, "lxml")
    # 构建首次提交搜索的payload
    current_payload = {
        'ctl00$ContentPlaceHolder1$btnSubmit1': 'Start Search',
        '__VIEWSTATE': soup.select_one('#__VIEWSTATE')['value'],
        '__EVENTVALIDATION': soup.select_one('#__EVENTVALIDATION')['value'],
        '__VIEWSTATEGENERATOR': soup.select_one('#__VIEWSTATEGENERATOR')['value']
    }

    all_facility_names = []
    while True:
        # POST请求获取当前页内容
        r = s.post(link, data=current_payload)
        soup = BeautifulSoup(r.text, "lxml")

        # 提取当前页所有机构名称
        for item in soup.select("#ctl00_ContentPlaceHolder1_DgFacils tr:has(> td)"):
            facility_name = item.select("td")[1].text.strip()
            all_facility_names.append(facility_name)
            print(facility_name)

        # 检测是否存在可跳转的下一页链接
        next_page_link = soup.select_one("a[href*='__doPostBack'][href*='Next']")
        if not next_page_link:
            break

        # 提取当前页最新的防伪字段,构建下一页请求的payload
        current_payload = {
            # 指向下一页按钮对应的服务器控件ID
            '__EVENTTARGET': 'ctl00$ContentPlaceHolder1$DgFacils$ctl00$ctl02$btnNext',
            '__EVENTARGUMENT': '',
            '__VIEWSTATE': soup.select_one('#__VIEWSTATE')['value'],
            '__EVENTVALIDATION': soup.select_one('#__EVENTVALIDATION')['value'],
            '__VIEWSTATEGENERATOR': soup.select_one('#__VIEWSTATEGENERATOR')['value']
        }

    print(f"共提取到{len(all_facility_names)}条机构名称")

调试注意事项

  • 若运行时出现服务器校验失败的情况,可在浏览器开发者工具的网络面板中,手动点击一次下一页操作,查看实际POST请求中__EVENTTARGET的真实值,替换代码中对应控件ID即可
  • 部分分页控件在最后一页会将下一页按钮设置为禁用状态,此时可额外判断元素的class属性,避免发送无效请求
  • __VIEWSTATE字段值可能包含特殊字符,requests库会自动完成URL编码,无需手动转义

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 16:24:04