Python爬取含多<a>标签HTML表格报索引越界解决方案
索引越界核心诱因
异常由4处代码逻辑缺陷共同触发:
- 未校验当前行
<td>标签数量,表格内的表头行、分隔行、合并单元格行的列数不足6个,直接按下标取columns[0]到columns[5]会直接触发索引越界 - 未判断单元格内是否存在
<a>标签,部分单元格无链接时直接访问.a属性会返回None,后续取.contents时会抛出空对象异常 .contents返回值是标签子节点列表,包含换行符、注释等非文本节点,直接对列表调用字符串的.strip()方法会触发类型错误- DataFrame行追加逻辑写在
for循环外部,仅会写入最后一行采集结果,且Remark字段错误赋值为site变量值
修正后可运行代码
import pandas as pd from bs4 import BeautifulSoup import requests # 初始化结果表 df = pd.DataFrame(columns=['ID', 'Date', 'Payload(s)', 'Launch Vehicle', 'Site', 'Remark']) # 以下为页面获取逻辑,可直接替换为你已有的table_body生成代码 resp = requests.get("https://space.skyrocket.de/doc_chr/lau2019.htm", timeout=10) resp.encoding = 'utf-8' soup = BeautifulSoup(resp.text, 'html.parser') table_body = soup.find('table', id='chronlist').tbody for row in table_body.find_all('tr'): columns = row.find_all('td') # 列数不足6的行直接跳过 if len(columns) < 6: continue row_data = {} row_data['ID'] = columns[0].text.strip() row_data['Date'] = columns[1].text.strip() # 兼容载荷列多a标签、无a标签场景 payload_links = columns[2].find_all('a') if payload_links: payload_text = [link.text.strip().strip('&0.') for link in payload_links] row_data['Payload(s)'] = '; '.join(payload_text) else: row_data['Payload(s)'] = columns[2].text.strip().strip('&0.') # 兼容运载火箭列无a标签场景 lv_link = columns[3].find('a') if lv_link: row_data['Launch Vehicle'] = lv_link.text.strip().strip('&0.') else: row_data['Launch Vehicle'] = columns[3].text.strip().strip('&0.') row_data['Site'] = columns[4].text.strip() row_data['Remark'] = columns[5].text.strip() # 行追加逻辑放在循环内部 df = pd.concat([df, pd.DataFrame([row_data])], ignore_index=True) df.to_csv('GunterPage.csv', index=True)
关键调整说明
- 新增行结构校验:循环内先判断当前行
<td>数量≥6才执行提取,自动跳过不符合结构的特殊行 - 替换硬编码取链接的写法:改用
find()/find_all()获取链接标签,判断标签存在后再提取文本,兼容无链接的单元格 - 多载荷适配:自动识别单元格内多个
<a>标签,提取所有载荷名称后用分号拼接,适配目标页面单单元格多载荷条目的结构 - 统一用
.text属性提取可见文本,避免直接操作.contents拿到非文本节点触发类型错误 - 修正DataFrame写入逻辑位置,修复原代码仅写入最后一行数据的问题,同时修正
Remark字段的赋值错误
内容的提问来源于stack exchange,提问作者Hussain Bokhari
相关产品推荐
相关产品推荐

