影刀RPA进阶教程:复杂网页表格提取攻略合并单元格多级表头与不规则表格的通用解法
你以为网页表格采集就是"找到表格→读取→写入Excel"?
那是标准化表格的玩法。真实世界里的网页表格,长这样:
- 合并单元格——第一行跨了三列,第二行又拆开
- 多级表头——品类、一级指标、二级指标,三层叠在一起
- 单元格里塞了图片和链接——不是纯文本
- 表格长得像表格,实际上是div+css搭出来的
这篇文章专治各种"不规矩"的网页表格。
先判断:这是真表格还是假表格

打开F12检查元素,看外层标签:
真表格(table标签)
<table>
<tr>
<td>数据1</td>
<td>数据2</td>
</tr>
</table>
这种最简单,影刀"批量抓取表格数据"指令直接搞定。
假表格(div模拟)
<div class="table">
<div class="row">
<div class="cell">数据1</div>
<div class="cell">数据2</div>
</div>
</div>
这种需要逐行逐列定位,不能用"批量抓取表格"。
第一步先判类型,后面的策略完全不同。

场景一:合并单元格处理
合并单元格是最常见的"不规则表格"。
HTML里通过 rowspan(跨行合并)和 colspan(跨列合并)实现:
<table>
<tr>
<td rowspan="2">华东区</td>
<td>上海</td>
<td>10,000</td>
</tr>
<tr>
<td>杭州</td>
<td>8,000</td>
</tr>
</table>
期望的Excel结果:
拼多多店群自动化报活动上架!
| 华东区 | 上海 | 10,000 |
![]() |
| 华东区 | 杭州 | 8,000 |
方案:Python+pandas读取
影刀的"批量抓取表格数据"指令对合并单元格的还原不太理想。
用Python的pandas更可靠:
import pandas as pd
# 直接读取页面上的table
tables = pd.read_html('https://example.com/report.html')
# tables是一个列表,取第一个
df = tables[0]
# 向前填充合并单元格
df = df.fillna(method='ffill')
# 保存
df.to_excel('output.xlsx', index=False)
fillna(method='ffill') 是关键:它会用上方的非空值填充下方空值,正好解决合并单元格的问题。
在影刀中调用
1. 获取当前页面HTML(或直接用Python requests获取)
2. Python代码块:
import pandas as pd
df = pd.read_html(页面源码)[0]
df = df.fillna(method='ffill')
df.to_excel('merged_table.xlsx', index=False)
3. 读取生成的Excel

场景二:多级表头
这种表格长这样:
| 品类 | 销售额 | 利润 | 销售额 | 利润 |
| 电子 | 100 | 20 | 150 | 30 |
| 服装 | 80 | 25 | 90 | 28 |
第一行是大分类(季度),第二行是具体指标。读取时会把第一行和第二行读成独立的行。
方案:手动拼接表头
import pandas as pd
df = pd.read_html('page.html', header=None)[0]
# 前两行是表头
header_row1 = df.iloc[0].fillna(method='ffill')
header_row2 = df.iloc[1]
# 拼接:列0直接用第二行,其他列用"季度_指标"格式
new_columns = []
for i in range(len(header_row1)):
if i == 0:
new_columns.append(str(header_row2[i]))
else:
new_columns.append(f"{header_row1[i]}_{header_row2[i]}")
# 取数据部分
df_data = df.iloc[2:].reset_index(drop=True)
df_data.columns = new_columns
df_data.to_excel('multi_header.xlsx', index=False)
结果是:
| 电子 | 100 | 20 | 150 | 30 |
![]() |
场景三:单元格里有图片/链接/按钮
有些表格的单元格不是纯文本:
<td>
<img src="star.png" class="rating">
<span class="score">4.5</span>
<a href="/detail/123">商品名称</a>
</td>
你只想要"4.5"和"商品名称",但直接取td的文本会拿到一堆废东西。
方案:精确XPath定位
不要取整个td,而是定位到具体元素:
# 取评分
//td[@class='rating-cell']/span[@class='score']/text()
# 取商品链接
//td[@class='name-cell']/a/text()
# 取链接href
//td[@class='name-cell']/a/@href
有时候写两个循环分别取不同类型的数据,比试图在一个循环里全取完更省心。

场景四:假表格——div+css模拟
有些现代化网站不用table标签,而是用div加CSS模拟表格:
<div class="ant-table-body">
<div class="ant-table-row">
<div class="ant-table-cell">数据A1</div>
<div class="ant-table-cell">数据A2</div>
</div>
<div class="ant-table-row">
<div class="ant-table-cell">数据B1</div>
<div class="ant-table-cell">数据B2</div>
</div>
</div>
方案:先定位行,再循环列
1. 获取所有行元素://div[contains(@class, 'ant-table-row')]
2. 循环每一行:
2.1 获取该行所有单元格:./div[contains(@class, 'ant-table-cell')]
2.2 循环每个单元格,提取文本
2.3 拼接成本行数据
3. 所有行处理完,写入Excel
缺点:顺序依赖CSS渲染,如果CSS没按视觉顺序排列,提取出来的顺序就是乱的。
对于分页的假表格,每页的结构是一样的,在循环里加翻页逻辑就行。

场景五:表里嵌套了另一个表格
<table>
<tr><td>基本信息</td></tr>
<tr>
<td>
<table> <!– 嵌套表格 –>
<tr><td>姓名</td><td>张三</td></tr>
<tr><td>年龄</td><td>25</td></tr>
</table>
</td>
</tr>
</table>
pandas读这种表格会把它展平成三列,很难还原结构。
方案:分开提取
1. 提取外层表格的基本信息
2. 对于包含嵌套表格的单元格:
2.1 单独定位嵌套的table元素
2.2 单独读取嵌套表格
2.3 以"主键值"关联回主表
3. 在Excel中用两个sheet分别存放外层和内层数据
不要试图把嵌套表格"展平"到一行——数据关系会乱。
TEMU店群矩阵自动化运营核价报活动
实战:万能表格提取封装
把上面学到的思路封装成一个处理流程:
函数:万能表格提取(url, 表头行数, 是否有合并单元格)
1. requests获取页面HTML
2. pandas.read_html()读取所有table
3. 遍历每个table:
3.1 如果 表头行数>1:
调用"多级表头拼接"
3.2 如果 有合并单元格:
调用fillna(method='ffill')
3.3 如果 表格行列混乱(可能是假表格):
跳过pandas,用XPath逐行逐列提取
4. 每个table存一个sheet
5. 输出xlsx文件
实际使用时要灵活——先看一眼页面源码,判断类型,再选策略,别一上来就硬套。
避坑清单
坑1:pandas.read_html()只读到第一个表格
# 错误:只读了第一个
df = pd.read_html(url)[0]
# 正确:先看看有几个
tables = pd.read_html(url)
print(f'找到 {len(tables)} 个表格')

# 可能需要的是第N个
df = tables[2] # 第三个
坑2:页面需要动态加载
pandas.read_html()只能读页面源码中的表格,JS动态渲染的它看不见。
解决:先用影刀打开页面、等表格加载完、获取完整HTML,再传给pandas。
坑3:空值被pandas删了
# 保留空值
df = pd.read_html(html, keep_default_na=False)[0]
坑4:数字被当成字符串
# 清理并转换
df['金额'] = df['金额'].str.replace('[¥,]', '', regex=True)
df['金额'] = pd.to_numeric(df['金额'], errors='coerce')
总结

网页表格提取的复杂度取决于表格的"规矩"程度:
- 标准table → 影刀批量抓取一行搞定
- 合并单元格 → pandas read_html + ffill
- 多级表头 → pandas + 手动拼接表头
- 假表格(div) → XPath逐行逐列
- 嵌套表格 → 分开提取、分sheet存储
遇到问题先F12看源码,判断类型再选策略。别上来就对着一个div表格用"批量抓取表格数据"——它不认得。
内容标签:#影刀RPA #数据采集 #网页表格 #pandas #XPath 作者:林焱 系列:影刀RPA进阶教程系列——攻克真实业务中的数据采集难题





