如何用pandas.read_html爬取多页无URL变化的网页表格?
动态分页爬取NUFORC数据的解决方案
方案一:用Selenium模拟浏览器翻页
这个网站分页时URL不变,属于动态加载内容,直接用pd.read_html只能拿到第一页。用Selenium可以模拟真实点击分页按钮,逐页加载数据:
步骤&代码
- 先安装依赖包和对应浏览器驱动(比如ChromeDriver要和Chrome版本匹配)
- 运行以下代码:
import pandas as pd from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time # 初始化Chrome浏览器 driver = webdriver.Chrome() driver.get('https://nuforc.org/subndx/?id=all') # 用来存所有页的数据 total_data = pd.DataFrame() # 总共1497页,循环遍历 for _ in range(1497): # 等表格加载出来再提取 WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.TAG_NAME, 'table')) ) # 提取当前页的表格 current_page = pd.read_html(driver.page_source, displayed_only=False)[0] total_data = pd.concat([total_data, current_page], ignore_index=True) # 点击下一页,碰到最后一页就退出循环 try: next_btn = WebDriverWait(driver, 5).until( EC.element_to_be_clickable((By.LINK_TEXT, 'Next >')) ) next_btn.click() time.sleep(1) # 给页面留加载时间,可根据网络情况调整 except: break # 关闭浏览器,保存数据 driver.quit() total_data.to_csv('nuforc_full_data.csv', index=False)
方案二:抓包直接请求分页接口(更高效)
通过浏览器开发者工具抓包发现,切换分页时网站会发送POST请求,表单参数里FROM是起始行号(第一页0,第二页100,以此类推),MAX是每页100行。直接用requests发送POST请求,不用模拟浏览器,速度更快:
代码示例
import pandas as pd import requests import time url = 'https://nuforc.org/subndx/?id=all' # 加个User-Agent假装是浏览器请求 headers = { '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' } total_data = pd.DataFrame() total_pages = 1497 per_page = 100 for page_num in range(total_pages): start_row = page_num * per_page # 构造表单数据 form_data = { 'MAX': str(per_page), 'FROM': str(start_row), 'SHOW': 'Results' } # 发送POST请求获取页面 resp = requests.post(url, headers=headers, data=form_data) # 解析表格 current_page = pd.read_html(resp.text, displayed_only=False)[0] total_data = pd.concat([total_data, current_page], ignore_index=True) # 加个小延迟,避免请求太频繁被封IP time.sleep(0.5) # 保存全量数据 total_data.to_csv('nuforc_full_data.csv', index=False)
小贴士
- 优先选方案二,速度快资源占用少;如果网站有反爬限制,再用方案一模拟真实浏览器
- 可以加异常捕获,比如请求失败时重试,避免中途出错前功尽弃
内容的提问来源于stack exchange,提问作者Emilio Mastriani
相关产品推荐
相关产品推荐

