如何抓取分页表格?求助抓取指定网站表格后续分页数据的方法
解决 Boone County Jail 居民数据的分页抓取问题
嘿,我懂你现在的困扰——第一页数据能顺利抓下来,但分页内容的抓取完全摸不着头绪对吧?别慌,咱们先拆解这个网站的分页逻辑,再把你的代码改成能自动爬完所有页面的版本。
首先得搞清楚这个网站的分页机制:它不是靠URL参数直接跳转,而是通过POST表单提交加载下一页数据的。你可以打开浏览器开发者工具(按F12),切换到「网络」标签,点击页面上的「Next Page」按钮,就能看到它发送的POST请求里带了哪些关键参数——比如当前页码、每页显示条数,还有几个固定的隐藏字段。
接下来是修改后的完整代码,能自动遍历所有分页并把数据写入CSV:
import csv import requests import time from bs4 import BeautifulSoup # 分页请求的目标接口 base_url = 'https://report.boonecountymo.org/mrcjava/servlet/SH01_MP.I00290s' # 初始表单参数,从浏览器POST请求中提取的核心参数 form_data = { 'MP': 'I00290s', 'Action': 'Next', 'First': '0', 'Last': '20', # 网站默认每页显示20条 'SEL': 'ALL', 'Sort': 'NAME', 'Page': '1' } # 初始化CSV文件并写入表头 with open('jail_residents.csv', 'w', newline='', encoding='utf-8') as csvfile: fieldnames = ['Last Name', 'First Name', 'Middle Name', 'Gender', 'Race', 'Age', 'City', 'State'] writer = csv.DictWriter(csvfile, fieldnames=fieldnames) writer.writeheader() while True: # 发送POST请求获取当前页数据 response = requests.post(base_url, data=form_data) soup = BeautifulSoup(response.content, 'html.parser') # 提取表格数据(跳过表头行) rows = soup.find_all('tr')[1:] # 如果当前页没有数据,说明到了最后一页,终止循环 if not rows: break # 遍历每行提取居民信息 for row in rows: cols = row.find_all('td') resident_info = { 'Last Name': cols[0].get_text(strip=True), 'First Name': cols[1].get_text(strip=True), 'Middle Name': cols[2].get_text(strip=True), 'Gender': cols[3].get_text(strip=True), 'Race': cols[4].get_text(strip=True), 'Age': cols[5].get_text(strip=True), 'City': cols[6].get_text(strip=True), 'State': cols[7].get_text(strip=True) } writer.writerow(resident_info) # 检查是否还有下一页 next_button = soup.find('a', text='Next Page') if not next_button: break # 更新分页参数,准备请求下一页 current_page = int(form_data['Page']) form_data['Page'] = str(current_page + 1) form_data['First'] = str(int(form_data['First']) + 20) form_data['Last'] = str(int(form_data['Last']) + 20) # 加1秒延迟,避免请求过于频繁被网站拦截 time.sleep(1) print("所有数据抓取完成,已保存到 jail_residents.csv 文件中")
代码关键细节说明:
- 表单参数:这些参数完全复刻了浏览器提交的内容,确保服务器能正确返回对应页面的数据,如果后续网站参数有变化,直接去开发者工具里复制最新的即可。
- 终止条件:设置了两个停止循环的判断——当前页没有数据行,或者找不到「Next Page」按钮,确保不会无限循环。
- 参数更新:每次循环后把页码加1,同时
First和Last参数各加20(对应每页20条数据的偏移量),保证请求的是下一页的内容。 - 请求延迟:添加
time.sleep(1)是为了模拟人类浏览的节奏,降低被网站反爬机制拦截的概率,这个时长可以根据实际情况调整。
直接运行这段代码就能自动爬完所有分页的数据啦,如果遇到参数失效的情况,再去浏览器里抓一次最新的POST参数替换掉form_data里的内容就行。
内容的提问来源于stack exchange,提问作者Madeleine Smith
相关产品推荐
相关产品推荐

