Python使用Requests发POST请求抓取同URL多页表格仅获首页求助
解决方案
该站点采用ASP.NET WebForms架构,分页逻辑依赖服务端回发机制,所有分页请求共用同一个URL,每次点击页码时浏览器会提交包含状态参数的POST请求,你可以按照如下修改代码实现全分页数据抓取:
核心实现逻辑
- 首次发起GET请求拉取初始页内容,提取第一页表格数据,同时获取页面隐藏字段
__VIEWSTATE、__EVENTVALIDATION以及所有分页按钮对应的__EVENTTARGET值 - 循环发起POST请求拉取后续分页内容:每次请求前将
__EVENTTARGET替换为对应页码的按钮ID,同时更新__VIEWSTATE、__EVENTVALIDATION为上一次请求返回的最新值 - 所有分页数据抓取完成后合并导出为CSV文件
修改后可运行代码
import requests from bs4 import BeautifulSoup import pandas as pd import time base_url = "https://www.ccilindia.com/OMMWCG.aspx" # 存储所有分页的表格数据 all_dfs = [] def get_page_data(session, page_target=None): if page_target is None: # 第一页用GET请求 resp = session.get(base_url) else: # 后续页用POST请求,动态替换触发事件目标 post_data = { "__EVENTTARGET": page_target, "__EVENTARGUMENT": "", "__VIEWSTATEGENERATOR": "00145D45", "__VIEWSTATEENCRYPTED": "", "__VIEWSTATE": session.viewstate, "__EVENTVALIDATION": session.eventvalidation } resp = session.post(base_url, data=post_data) # 解析当前页内容 soup = BeautifulSoup(resp.content, 'html.parser') # 提取更新后的状态参数存储到session对象中供下一次请求使用 session.viewstate = soup.find("input", id="__VIEWSTATE")["value"] session.eventvalidation = soup.find("input", id="__EVENTVALIDATION")["value"] # 提取当前页表格 df = pd.read_html(resp.content, attrs={'id': 'grdMWCG'})[0] # 提取当前页所有可用的分页按钮target值,用于后续分页请求 page_targets = [] for page_btn in soup.select("table#grdMWCG tr:last-child a"): href = page_btn.get("href", "") if "grdMWCG" in href: # 从href中提取分页按钮的事件目标,格式为javascript:__doPostBack('grdMWCG$ctl29$ctl01','') target = href.split("'")[1] page_targets.append(target) return df, list(set(page_targets)) if __name__ == "__main__": with requests.Session() as req: # 增加请求头避免被站点拦截 req.headers.update({ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" }) # 获取第一页数据和所有分页按钮 first_df, page_targets = get_page_data(req) all_dfs.append(first_df) # 循环抓取剩余分页 for target in page_targets: # 适当增加请求间隔避免触发站点访问限制 time.sleep(1) df, _ = get_page_data(req, target) all_dfs.append(df) # 合并所有数据并去重 final_df = pd.concat(all_dfs, ignore_index=True) final_df = final_df.drop_duplicates(ignore_index=True) print(f"共抓取到{len(final_df)}条数据") final_df.to_csv("ccil_all.csv", index=False)
注意事项
- 站点仅在特定时段开放数据展示,若抓取时无表格返回请确认当前时段是否属于数据开放时间
- 分页数量不固定,代码会自动识别当前所有可用分页,无需手动指定分页数量
- 若站点后续调整分页按钮格式,可自行调整分页按钮的CSS选择器提取逻辑
- 可以根据实际情况调整请求间隔时间,避免被站点限制访问
内容的提问来源于stack exchange,提问作者Tech Bro
相关产品推荐
相关产品推荐

