公司动态

Python如何使用XPath提取表格内容

📅 2026/8/17 18:53:52
Python如何使用XPath提取表格内容
前言在爬虫数据采集场景中网页Table表格是非常典型的结构化数据榜单、统计报表、参数清单等大量网页都会使用表格展示数据。解析网页数据常见方案正则表达式、BeautifulSoup、XPath。对比来看正则表达式适合简单文本处理嵌套标签极易出错BeautifulSoup API友好但复杂筛选书写繁琐XPath基于文档层级定位语法简洁精准筛选节点搭配lxml解析速度优秀是抓取表格数据的热门选择。本文结合实战案例讲解如何利用Python XPath提取表格表头、行数据封装通用解析代码同时整理开发中高频踩坑点。一、环境准备我们使用两大核心库requests请求网页获取HTML源码lxmlHTML解析器支持完整XPath语法安装命令pip install requests lxml二、HTML表格基础结构认知标准网页表格标签层级table thead tr th姓名/th th年龄/th th城市/th /tr /thead tbody tr td张三/td td22/td td重庆/td /tr tr td李四/td td25/td td成都/td /tr /tbody /table标签说明table表格根标签thead表头区域th代表表头单元格tbody表格主体数据区域tr表格单行td普通数据单元格三、表格常用XPath表达式# 匹配页面中所有表格下的表头文本 //table//th/text() # 获取表格内所有行包含表头行 //table//tr # 只获取tbody内数据行过滤表头 //table//tbody//tr # 获取单行内所有单元格文本 .//td/text() # 指定id的表格精准定位推荐避免页面多个表格干扰 //table[iddata-table]//tbody//tr小知识点//代表跨层级搜索.代表在当前节点下继续搜索循环遍历tr的时候必须使用.。四、实战案例1解析本地HTML表格先模拟一段HTML源码直接解析不发起网络请求方便测试from lxml import etree # 模拟网页HTML html table thead tr th姓名/th th年龄/th th城市/th /tr /thead tbody tr td张三/td td22/td td重庆/td /tr tr td李四/td td25/td td成都/td /tr /tbody /table # 构建HTML解析对象 tree etree.HTML(html) # 提取表头 headers tree.xpath(//table//th/text()) print(表头, headers) # 提取所有数据行 rows tree.xpath(//table//tbody//tr) table_data [] for row in rows: # .//td 代表当前tr节点下查找td cell_text row.xpath(.//td/text()) table_data.append(cell_text) print(表格数据, table_data)运行结果表头 [姓名, 年龄, 城市] 表格数据 [[张三, 22, 重庆], [李四, 25, 成都]]我们可以把表头和数据结合生成字典列表结构更友好result [dict(zip(headers, item)) for item in table_data] print(结构化字典数据, result)五、实战案例2抓取线上网页表格结合requests获取远程网页通用模板import requests from lxml import etree headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 } url 目标网页地址 resp requests.get(url, headersheaders) resp.encoding resp.apparent_encoding tree etree.HTML(resp.text) # 修改XPath适配目标页面 th_list tree.xpath(//table//th/text()) tr_list tree.xpath(//table//tbody//tr) data_list [] for tr in tr_list: td_list tr.xpath(.//td/text()) data_list.append(td_list) print(data_list)六、常见问题与避坑指南1. 页面存在多个table抓取数据错乱解决方法通过id、class精准定位表格不要直接使用//table//table[classtable-data]//tbody//tr2. td内部存在a、span等子标签text()拿不到全部文本text()只能获取当前标签直接文本内部标签文本会丢失。改用string()或者xpath(.//td//text())# 提取单元格内所有文本包含子标签文字 texts row.xpath(.//td[1]//text()) content .join([i.strip() for i in texts])3. 文本存在大量换行、空格增加清洗逻辑封装工具函数def clean_text(text): if not text: return return text.strip().replace(\n, ).replace(\r, )4. 动态渲染表格JS加载数据requests只能拿到静态HTML如果表格由Ajax、Vue/React动态生成lxml无法获取内容。解决方案使用Playwright、Selenium加载完整页面。5. 部分网页没有thead表头直接放在第一行tr不要强制匹配thead灵活调整XPath表达式。七、封装通用表格解析函数可以直接复用在项目中from lxml import etree def parse_table(html: str, table_xpath: str //table): 通用表格解析函数 :param html: html源码 :param table_xpath: 表格定位xpath :return: 表头、字典格式表格数据 tree etree.HTML(html) # 提取表头 headers tree.xpath(f{table_xpath}//th/text()) headers [h.strip() for h in headers if h.strip()] # 提取数据行 rows tree.xpath(f{table_xpath}//tbody//tr) result [] for tr in rows: cells tr.xpath(.//td//text()) cells [c.strip() for c in cells if c.strip()] if len(cells) len(headers): result.append(dict(zip(headers, cells))) return headers, result总结使用lxml.etree加载HTML配合XPath实现表格节点筛选遍历tr时内部单元格查找必须使用.//td代表当前行内搜索优先通过id/class精准定位表格避免多表格干扰遇到单元格嵌套标签使用//text()获取全部文本并清洗静态页面适用lxmlJS动态渲染表格需要使用浏览器自动化工具。如果你经常做网页采集这套XPath解析表格方案可以作为基础模板根据不同网页结构微调XPath表达式即可快速复用。