根本解法是用lxml+xpath精确锚定路径,如//table[1]/tr[3]/td[2],而非//td;需处理colspan/rowspan错位、js动态渲染、html不规范等问题,并结合开发者工具确认dom层级。

用 lxml 的 xpath 定位嵌套 table 里的目标单元格
直接靠 BeautifulSoup.find_all("td") 很容易拿到错层数据——嵌套 table 里同名标签会混在一起。根本解法是用 lxml + xpath 精确锚定路径。
关键不是“找所有 td”,而是“找某个父 table 下第几行第几列的 td”。比如要取主表中第 3 行、第 2 列的值,且该单元格内还嵌了一个 table,就得写://table[1]/tr[3]/td[2],而不是 //td。
-
xpath中[1]是从 1 开始计数,不是 Python 的 0 起始 - 嵌套
table默认会污染全局//td结果,必须用相对路径(如.//td)配合上下文节点 - 如果目标
td内含多个文本节点或换行,用.text_content().strip()比.get_text()更可靠
处理 colspan/rowspan 导致的行列错位问题
浏览器渲染时自动合并单元格,但 HTML 源码里只靠 colspan 和 rowspan 属性隐式表达——爬虫不会自动补空单元格,直接按 tr→td 嵌套遍历会错位。
真正能对齐行列的方案是模拟浏览器逻辑:先解析所有 tr,再逐行构建二维坐标矩阵,根据 colspan 向右占位、rowspan 向下占位,最后填入实际 td 内容。
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
- 手动实现行列映射比依赖第三方库更可控,尤其当表格结构不规则时
- 注意
colspan="0"在某些旧页面中表示“撑满剩余列”,需特殊判断 - 若只需提取某几个固定位置的值(如“负责人”所在行右侧单元格),可跳过完整建模,改用
xpath配合following-sibling定位
应对 JavaScript 动态生成的 Table 结构
源码里 <table> 标签为空或只有骨架,真实数据由 JS 插入——此时 <code>requests + lxml 拿不到内容,必须切换执行环境。
优先选 Playwright(非 Selenium),它默认等待网络空闲且支持无头模式稳定运行;加载完成后,用 page.content() 获取渲染后 HTML,再交给 lxml 解析。
- 别用
page.wait_for_timeout(3000)硬等,应监听具体table元素出现:page.wait_for_selector("table#data-table", timeout=10000) - 动态表格常带 class 名如
loading或empty,检查这些状态类比等超时更健壮 - 如果页面用 React/Vue 渲染,可能需要触发滚动或点击“加载更多”,否则部分
table不会初始化
避免因 HTML 结构不规范导致的解析中断
现实网页中 table 常缺 tbody、tr 被 div 替代、甚至 td 直接子元素是 span 而非文本——lxml 默认严格解析会丢节点,BeautifulSoup 的容错性反而更实用。
折中做法:用 BeautifulSoup 的 html.parser 或 lxml 解析器预处理 HTML,修复缺失闭合标签;再转成 lxml.etree 对象跑 xpath,兼顾鲁棒性和定位精度。
- 修复后仍可能有孤立
td漂浮在table外,用xpath加条件过滤://table//td[ancestor::table] - 某些 CMS 输出的表格会把样式写进
style属性里(如display:none),需额外检查可见性逻辑 - 表格跨页时(如分页组件),
iframe或异步加载的后续页需单独请求,不能只靠初始 HTML
嵌套 table 的解析难点不在语法层面,而在于你是否清楚当前目标值在 DOM 树中的真实层级关系——多看浏览器开发者工具里的“Elements”面板,比反复试错 xpath 有效得多。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










