使用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
相关产品推荐
相关产品推荐

