You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Python和Pandas的网页爬取:分页数据获取问题

分页爬取世界田联800米室内成绩数据的实现思路与代码

核心思路

目标网站的分页逻辑通过URL中的page参数控制(比如page=1对应第一页),只需循环修改该参数值,依次爬取每一页的表格数据后合并即可。关键是先确定总页数,避免无效循环。

具体实现步骤

  1. 解析总页数:
    pd.read_html仅能获取表格数据,无法读取分页信息,因此需要先用requests获取页面源码,再通过BeautifulSoup解析总页数。观察目标页面的分页区域,会存在类似Page 1 of 12的文本,从中提取总页数数值。

  2. 循环爬取每页数据:
    基于基础URL,循环替换page参数的值,依次爬取每一页的表格,将所有页面的DataFrame合并为一个大的DataFrame。

  3. 异常处理:
    加入简单的异常判断,当请求返回非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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 00:45:46