Python pandas爬取网页表格导出CSV报列数不匹配仅导出首行
问题现象
导出网页表格数据到CSV时,最终生成的文件仅保留第一行内容,代码执行过程中返回报错:
cannot set a row with mismatched columns
原实现代码如下:
from curses import color_content from email import header from lib2to3.pgen2.token import COLONEQUAL from wsgiref import headers import requests from bs4 import BeautifulSoup import pandas as pd #page to access url = 'site.xxx' #request.get page = requests.get(url) #beatifulSoup soup = BeautifulSoup(page.text, 'lxml') #extract table table1=soup.find('table',id='table28') #extract column headers = [] for i in table1.find_all('th'): title = i.text headers.append(title) #create dataframe mydata=pd.DataFrame(columns=headers) # Create a for loop to fill mydata for j in table1.find_all('tr')[1:]: row_data = j.find_all('td') row = [i.text for i in row_data] length = len(mydata) mydata.loc[length] = row # Export to csv mydata.to_csv('classifica_piloti2.csv', index=False)# Try to read csv mydata2 = pd.read_csv('classifica_piloti2.csv')
报错原因
报错的直接触发条件是:写入DataFrame的某一行数据的元素个数,和DataFrame定义的列数不一致。
对应到你的代码场景,通常是两个问题导致的:
- 网页表格存在带
colspan/rowspan属性的跨行、跨列单元格,直接通过find_all('td')抓取单元格时,不会自动补全被合并的占位单元格,导致该行解析出的元素数量比表头列数少 - 代码开头导入了多个无用模块,其中
from wsgiref import headers和你后续自定义存储表头的headers变量重名,存在变量污染隐患;同时你提取表头时没有做内容清洗,有可能把嵌套的子表头、多余的空th标签也纳入了表头列表,导致表头列数和实际数据行的单元格数不匹配。
修复方法
方法1:手动对齐行与表头的长度
保留原有BeautifulSoup解析逻辑,在逐行写入前做列数对齐,短于表头的行补空值,长于表头的行截断多余内容,同时删除开头无用的冗余导入、给文本内容加空白清洗:
import requests from bs4 import BeautifulSoup import pandas as pd url = 'site.xxx' page = requests.get(url) soup = BeautifulSoup(page.text, 'lxml') table1 = soup.find('table', id='table28') # 提取并清洗表头 headers = [] for i in table1.find_all('th'): title = i.text.strip() headers.append(title) mydata = pd.DataFrame(columns=headers) # 逐行填充数据 for j in table1.find_all('tr')[1:]: row_data = j.find_all('td') row = [i.text.strip() for i in row_data] # 对齐列数 if len(row) < len(headers): row += [''] * (len(headers) - len(row)) elif len(row) > len(headers): # 若需要排查异常行,可在此处加print(row)打印异常内容 row = row[:len(headers)] mydata.loc[len(mydata)] = row mydata.to_csv('classifica_piloti2.csv', index=False)
方法2:用pandas内置方法直接解析表格
pandas自带的read_html方法可以自动处理大部分网页表格的跨行跨列、列数不匹配问题,不需要手写逐行解析逻辑,代码更简洁:
import requests import pandas as pd url = 'site.xxx' page = requests.get(url) # 匹配id为table28的表格,取第一个匹配结果 mydata = pd.read_html(page.text, attrs={'id': 'table28'})[0] mydata.to_csv('classifica_piloti2.csv', index=False)
内容的提问来源于stack exchange,提问作者Enk17_
相关产品推荐
相关产品推荐

