把网页里的 HTML 表格转 CSV: 抓数据、对账单、报表的本地做法
网页上看到一张表格想导进 Excel, 复制粘贴常常错位乱码。这篇讲清楚 HTML 表格转 CSV 的原理: tr 怎么变行, td 怎么变列, 单元格里有逗号怎么转义, 还有为什么整个过程都在本地浏览器里跑。
网页上的表格想导进 Excel? 先搞懂 HTML 表格转 CSV 这件事
我经常碰到这种场景: 某个政府开放数据页、某个供应商规格页、某个论坛排行榜, 数据明明就摆在一张表格里, 偏偏没有"下载 CSV"的按钮。你框选、复制、粘进 Excel, 结果要么列全挤成一坨, 要么中文变成一串问号。问题不在你手抖, 而在 HTML 表格和 CSV 是两套完全不同的结构, 中间这层转换不做对, 数据就会偏。
这篇就把这层转换讲透: 一张 <table> 是怎么变成一行行 CSV 的, 哪些地方最容易翻车, 以及为什么我宁可用一个纯本地的工具也不把整页源码丢给在线服务。
tr 变成行, td 变成列
HTML 表格的骨架很简单: <table> 里一个 <tr> 是一行, <tr> 里每个 <td> (或表头里的 <th>) 是一格。CSV 的规则也很简单: 一行文本是一条记录, 行内用逗号分隔出一个个字段。
所以最朴素的转换就是: 遍历每个 <tr>, 把里面的 <td> 文本按逗号拼起来, 行与行之间换行。比如这段:
<table>
<tr><th>城市</th><th>人口</th><th>备注</th></tr>
<tr><td>上海</td><td>2487</td><td>常住, 含郊区</td></tr>
<tr><td>北京</td><td>2189</td><td>含通勤人口</td></tr>
</table>
直接拼出来想要的结果是:
城市,人口,备注
上海,2487,"常住, 含郊区"
北京,2189,含通勤人口
注意第二行那个"常住, 含郊区"被双引号包起来了, 这不是装饰, 是必须的。
单元格里有逗号, 必须加引号
这是新手最常踩的坑。CSV 用逗号分隔字段, 那如果某个单元格的内容本身就含逗号呢? 上面例子里"常住, 含郊区"如果不加引号, Excel 会把它读成两个字段, 整行就从 3 列变成 4 列, 后面所有数据全错位。
RFC 4180 这个 CSV 规范定得很清楚: 字段里出现逗号、双引号、换行符这三种字符之一, 就要把整个字段用双引号包住; 字段内部本来就有的双引号, 要写成两个连续的双引号来转义。比如一个单元格内容是 他说"对", 转出来要写成 "他说""对"""。
这套引号逻辑看着琐碎, 但漏掉任何一种情况, 导出的 CSV 在别人电脑上打开就可能整列错位。我做 HTML 表格转 CSV 工具 时, 这部分是按规范逐字符判断的, 你不用自己记这些规则。
th 当表头, 但表头检测没那么简单
第一行到底是表头还是数据? 这决定了 JSON 输出里键名怎么取, 也决定了导进数据库时第一行要不要跳过。
工具的判断分三档。最理想的情况是源 HTML 里有 <thead> 标签, 那就听它的, 哪怕是多行表头也能按 " / " 把键名拼起来。如果没有 <thead>, 就看第一行的内容: 全是文本类的字 (像"城市""人口") 就当表头, 全是数字 (像 1, 2, 3 或 12.5%, 8.0%) 就不当, 因为没人会拿一行数字当列名。当然你也能手动强制选"首行为表头"或"无表头"。
这里有个真实的坑: 如果第一行其实是数据, 你却强制选了"首行为表头", JSON 输出的键名就会变成 1、2.50 这种数字, 语法合法但完全没法用。默认让它自动判断最稳。
一段真实的输入输出例子
举个稍微复杂点的, 带表头检测和逗号转义的。输入这段 HTML:
<table>
<thead><tr><th>商品</th><th>单价</th><th>规格</th></tr></thead>
<tbody>
<tr><td>螺丝刀</td><td>19.9</td><td>一字, 十字两支装</td></tr>
<tr><td>电烙铁</td><td>89</td><td>60W</td></tr>
</tbody>
</table>
转出来的 CSV 是:
商品,单价,规格
螺丝刀,19.9,"一字, 十字两支装"
电烙铁,89,60W
<thead> 里的三个 <th> 被识别成表头那一行, "一字, 十字两支装"含逗号所以被双引号包住, 而 "60W" 没有特殊字符就原样输出。这份 CSV 拿去 Excel 双击、或者 pandas read_csv、或者灌进数据库, 都不会错位。
为什么本地处理这件事我看得很重
抓网页数据这个场景, 粘进去的往往不只是表格。你要是保存整页 HTML 再粘源码, 里面可能混着邮箱地址、带 session 的 URL、内部域名、cookie 弹窗这些东西。这些信息发到别人的服务器, 是我不想承担的风险。
所以工具整条流水线 (解析 HTML、重建网格、序列化成 CSV) 全是浏览器标签页里跑的纯 JavaScript, 一个字节都不上传。我自己抓某次供应商对账单时就是断网跑的, 数据根本没离开过那台笔记本。顺手提一句, 抓中文数据导 Excel 记得把 BOM 选项勾上, 不然中文 Windows 的 Excel 会按本地编码读, 又变乱码。
转完 CSV 想接着加工的话, 可以再走 CSV 转 JSON 工具 把它变成对象数组, 喂给代码或接口都方便。
抓网页表格这件事, 难的从来不是复制粘贴本身, 而是逗号转义、表头判断、编码这些容易被忽略的细节。把这几样做对, 一张乱糟糟的网页表格才能干净地落进你的电子表格里。
Made by Toolora · Updated 2026-06-13