如何使用Python爬取同URL下HTML表格的多页分页数据
问题排查与修复方案
你的翻页逻辑失效核心是两个硬伤:
- 初始请求写法错误:
requests.get.get(url)属于笔误,根本没有正确发起初始GET请求,拿到的第一页soup本身就不完整 - WebForm回发参数填错:这类ASP.NET站点的分页是通过
__doPostBack触发的,你把__EVENTTARGET留空了,服务端收不到正确的控件触发标识,直接默认返回第一页内容。实际这个站点分页触发时,__EVENTTARGET固定为分页表格的服务端IDctl00$ContentPlaceHolder1$grdJobs,__EVENTARGUMENT才是你之前填的页码参数。
另外你直接匹配所有table标签的写法太粗糙,会把页面里用来布局的无关表格一起打印出来,拿不到干净的职位数据。
可直接运行的修正代码
用requests.Session()维持会话自动处理cookie,加正常的User-Agent避免被拦截,精准定位职位表格:
import requests from bs4 import BeautifulSoup target_url = "https://newbraunfels.tedk12.com/hire/Index.aspx" request_headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36" } # 初始化会话,自动维护Cookie避免回发验证失败 session = requests.Session() def parse_job_list(soup): """从当前页面解析职位数据""" job_table = soup.select_one("#ContentPlaceHolder1_grdJobs") if not job_table: return [] job_list = [] # 跳过表头行,遍历数据行 for row in job_table.select("tr")[1:]: columns = [col.get_text(strip=True) for col in row.select("td")] if len(columns) >=4: job_list.append({ "job_title": columns[0], "department": columns[1], "post_date": columns[2], "deadline": columns[3] }) return job_list def get_target_page(page_num): """获取指定页码的页面soup""" if page_num == 1: resp = session.get(target_url, headers=request_headers) return BeautifulSoup(resp.content, "lxml") # 非首页构造POST回发请求 form_payload = {} # 自动填充当前页所有隐藏表单字段 for input_tag in soup.select("input"): input_name = input_tag.get("name") if input_name: form_payload[input_name] = input_tag.get("value", "") # 填充正确的回发参数 form_payload["__EVENTTARGET"] = "ctl00$ContentPlaceHolder1_grdJobs" form_payload["__EVENTARGUMENT"] = f"PageIndexNumber${page_num}" resp = session.post(target_url, data=form_payload, headers=request_headers) return BeautifulSoup(resp.content, "lxml") # 爬取全部4页数据 all_jobs = [] current_soup = None for page in range(1, 5): print(f"正在抓取第{page}页...") current_soup = get_target_page(page) page_jobs = parse_job_list(current_soup) all_jobs.extend(page_jobs) print(f"第{page}页抓取完成,共{len(page_jobs)}条职位") # 打印结果 print("\n===== 全部招聘职位 =====") for idx, job in enumerate(all_jobs, 1): print(f"{idx}. {job['job_title']} | 所属部门:{job['department']} | 发布时间:{job['post_date']} | 申请截止:{job['deadline']}")
注意事项
- 如果后续站点前端改版导致控件ID变化,直接打开浏览器F12,点分页按钮看触发的
__doPostBack函数参数:第一个参数就是__EVENTTARGET需要填的值,第二个参数就是__EVENTARGUMENT的格式,替换即可 - 不要频繁短时间请求,容易被站点防火墙拦截
- 代码默认爬取全部4页内容,如果要调整页码范围,修改
range(1,5)里的结束值即可
内容的提问来源于stack exchange,提问作者EAA
相关产品推荐
相关产品推荐

