基于Python和Pandas的网页爬取:分页数据获取问题
分页爬取世界田联800米室内成绩数据的实现思路与代码
核心思路
目标网站的分页逻辑通过URL中的page参数控制(比如page=1对应第一页),只需循环修改该参数值,依次爬取每一页的表格数据后合并即可。关键是先确定总页数,避免无效循环。
具体实现步骤
解析总页数:
pd.read_html仅能获取表格数据,无法读取分页信息,因此需要先用requests获取页面源码,再通过BeautifulSoup解析总页数。观察目标页面的分页区域,会存在类似Page 1 of 12的文本,从中提取总页数数值。循环爬取每页数据:
基于基础URL,循环替换page参数的值,依次爬取每一页的表格,将所有页面的DataFrame合并为一个大的DataFrame。异常处理:
加入简单的异常判断,当请求返回非200状态码或页面无表格数据时,停止当前页爬取并继续下一页,避免程序报错中断。
完整代码示例
import pandas as pd import requests from bs4 import BeautifulSoup import time # 基础URL,将page参数设为占位符 base_url = "https://www.worldathletics.org/records/toplists/middle-long/800-metres/indoor/men/senior/2023?regionType=world&timing=electronic&page={}&bestResultsOnly=false&oversizedTrack=regular" # 获取总页数 first_page_url = base_url.format(1) response = requests.get(first_page_url) soup = BeautifulSoup(response.text, 'html.parser') # 解析分页文本(示例文本:"Page 1 of 12") pagination_text = soup.find('div', class_='pagination-info').text.strip() total_pages = int(pagination_text.split('of')[-1].strip()) # 循环爬取所有页面 total_df = pd.DataFrame() for page in range(1, total_pages + 1): print(f"正在爬取第 {page} 页...") current_url = base_url.format(page) try: dfs = pd.read_html(current_url, parse_dates=True) page_df = dfs[0] total_df = pd.concat([total_df, page_df], ignore_index=True) # 控制请求间隔,避免被封禁 time.sleep(1) except Exception as e: print(f"爬取第 {page} 页失败: {str(e)}") continue # 保存合并后的数据 total_df.to_csv('2023_I_M_800_all_pages.csv', index=False) print("所有页面爬取完成,已保存到CSV文件。")
注意事项
- 务必添加请求间隔(如
time.sleep(1)),避免短时间内大量请求导致IP被网站封禁。 - 若网站分页文本的HTML结构发生变化,需调整
BeautifulSoup的解析逻辑(比如修改查找的class名称或标签)。
内容的提问来源于stack exchange,提问作者CarlosFC
相关产品推荐
相关产品推荐

