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

使用BeautifulSoup爬取表格仅获表头,后续数据无法提取求助

问题分析与解决

核心问题1:静态请求拿不到动态加载的数据

你用requests.get()获取的是页面的静态HTML源码,但目标网站的会员列表表格数据是通过JavaScript动态加载的,静态源码里只有表头<tr>,没有后续的行数据。所以table.findAll('tr')只会返回表头这一行,自然不会执行else分支的代码,也就没有数据写入CSV。

核心问题2:代码逻辑的潜在错误(假设能拿到数据的情况下)

就算能获取到所有行,你的代码逻辑也存在严重问题:

  • 每次循环都打开/关闭CSV文件,效率极低,还容易引发写入异常
  • 每append一行数据到rows,就直接尝试取rows[j], rows[j+1], rows[j+2], rows[j+3],但此时rows里只有当前刚添加的1条数据,直接访问后续索引会触发索引越界错误
  • j的递增逻辑完全不符合实际行的数量,会导致数据读取混乱

解决思路

方案1:用Selenium模拟浏览器渲染(适合新手)

因为数据是JS动态加载的,需要模拟浏览器运行页面来获取完整数据:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup
from csv import writer
import time

# 配置无头浏览器(不弹出窗口)
chrome_options = Options()
chrome_options.add_argument('--headless=new')
driver = webdriver.Chrome(options=chrome_options)

driver.get('https://www.cfpc.ca/en/members-list')
# 等待数据加载,可根据实际加载速度调整等待时间
time.sleep(3)

soup = BeautifulSoup(driver.page_source, 'lxml')
table = soup.find('table', id='memberlist-table')

# 提取表头和所有行数据
header = [th.text.strip() for th in table.find('tr').find_all('th')]
rows_data = []
for row in table.find_all('tr')[1:]:
    row_content = [td.text.strip() for td in row.find_all('td')]
    rows_data.append(row_content)

# 一次性写入CSV,只打开一次文件
with open('test1.csv', 'w', newline='', encoding='utf-8') as f:
    thewriter = writer(f)
    thewriter.writerow(header)
    thewriter.writerows(rows_data)

driver.quit()

方案2:直接抓取数据接口(更高效)

打开浏览器开发者工具的Network面板,刷新页面后找到加载会员数据的API接口,直接请求接口获取JSON格式的数据,再转换为CSV。这种方式不需要模拟浏览器,效率更高,是爬虫的最优解。

补充提醒

  • 注意网站的反爬规则,不要频繁发起请求,避免IP被封禁
  • 写入CSV时建议指定encoding='utf-8',避免中文乱码

内容的提问来源于stack exchange,提问作者ndang22

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 13:54:50