Day 13 · AI 辅助解析:复杂表格和嵌套结构

发布时间:2026/8/15 22:32:08
Day 13 · AI 辅助解析:复杂表格和嵌套结构 「AI Python 系列」第 03 栏 · Python 爬虫实战全栏 15 篇 · 零成本跟完 作者梅雅达编程笔记首发CSDN摘要有些网页结构复杂到XPath根本写不出来——嵌套表格、混合排版、图文混排。这时候与其死磕HTML结构不如换个思路截图让视觉模型看图说话。Day 13教你用GLM-4V-Flash视觉模型直接把页面截图扔给它让它输出你要的结构化数据。对比文本模型和视觉模型各自的适用场景让你知道什么时候该用哪个。前面讲了用文本模型处理 HTML。但有些页面给你 HTML 也没用表格嵌套了好几层td里套div再套table数据散落在不同位置靠排版让人看懂HTML 结构完全没逻辑图片里包含文字信息比如价格标签是张图片Canvas渲染的图表数据这时候XPath、正则、甚至文本大模型都帮不了你。该请视觉模型上场了。一、视觉模型能做什么简单说你给它一张图片它告诉你图片里有什么。GLM-4V-Flash 是智谱的免费视觉模型可以理解图片内容并回答问题。我们的用法用DrissionPage把页面截图把截图发给 GLM-4V-Flash让模型从图片中提取你要的结构化数据返回 JSON不用分析 HTML不用写选择器你看到什么AI 就能提取什么。二、基础流程第一步页面截图用DrissionPage截图fromDrissionPageimportChromiumPage pageChromiumPage()page.get(https://example-complex-table.com/)# 全屏截图page.get_screenshot(pathpage_screenshot.png)# 或者只截某个区域注意page.ele 可能命中隐藏的布局表格# 建议遍历找第一个有宽高的可见表格避免 NoRectErrorelementNoneforeleinpage.eles(css:table):try:w,hele.rect.sizeifwandhandw0andh0:elementelebreakexceptException:continueifelementisNone:page.get_screenshot(pathtable_only.png)# 兜底整页截图else:element.scroll.to_see()# 滚动到表格位置确保完整渲染element.get_screenshot(pathtable_only.png)page.quit()踩坑提醒很多网站尤其是政府网站的第一个table是用来做页面布局的隐藏表格display:none没有宽高。直接用page.ele(css:table)再get_screenshot()会报NoRectError: 该元素没有位置及大小。上面的遍历写法可以自动跳过隐藏表格找到第一个真正可见的。第二步发给视觉模型importbase64fromopenaiimportOpenAI clientOpenAI(api_keyYOUR_API_KEY,base_urlhttps://open.bigmodel.cn/api/paas/v4/)# 读取图片并编码withopen(table_only.png,rb)asf:img_base64base64.b64encode(f.read()).decode()# 调用视觉模型responseclient.chat.completions.create(modelglm-4v-flash,# GLM-4V-Flash 视觉模型messages[{role:user,content:[{type:text,text:请从这张图片中的表格里提取所有数据返回 JSON 数组。每行一个对象字段名用表格的表头。},{type:image_url,image_url:{url:fdata:image/png;base64,{img_base64}}}]}])print(response.choices[0].message.content)就这么简单。截图 → 发给模型 → 拿到结果。三、实战从复杂公告页提取表格数据场景假设你要从政府网站提取一份公告中的表格数据。这个表格合并了单元格、嵌套了子表格HTML 结构极其复杂tableclassgovernment-noticetrtdcolspan32026年度重点项目公示/td/trtrtdrowspan2序号/tdtd项目名称/tdtd预算万元/td/trtrtdcolspan2详细信息/td/tr!-- 后面还有几十行嵌套结构 --/table用XPath提取写到你怀疑人生。用视觉模型解决 Day 13 示例代码视觉模型提取复杂表格 作者梅雅达编程笔记 fromDrissionPageimportChromiumPageimportbase64importjsonimporttimefromopenaiimportOpenAI clientOpenAI(api_keyYOUR_API_KEY,base_urlhttps://open.bigmodel.cn/api/paas/v4/)deffind_visible_table(page,timeout10):遍历页面所有 table返回第一个真正可见有宽高的元素。 政府网站常有隐藏的布局表格直接 page.ele 会报 NoRectError。 page.wait.ele_displayed(css:table,timeouttimeout)foreleinpage.eles(css:table):try:w,hele.rect.sizeifwandhandw0andh0:returneleexceptException:continuereturnNonedefscreenshot_table(page,path):截取页面中第一个可见表格找不到则整页截图兜底。tablefind_visible_table(page)iftableisNone:print(未找到可见表格改为整页截图)page.get_screenshot(pathpath)else:table.scroll.to_see()time.sleep(0.5)# 等滚动后的渲染table.get_screenshot(pathpath)defextract_table_from_image(image_path,prompt):用视觉模型从图片中提取结构化数据withopen(image_path,rb)asf:img_base64base64.b64encode(f.read()).decode()responseclient.chat.completions.create(modelglm-4v-flash,messages[{role:user,content:[{type:text,text:prompt},{type:image_url,image_url:{url:fdata:image/png;base64,{img_base64}}}]}],temperature0.1)contentresponse.choices[0].message.content.strip()# 提取 JSONifjsonincontent:contentcontent.split(json)[1].split()[0]elifincontent:contentcontent.split()[1].split()[0]returnjson.loads(content)defmain():# 1. 打开页面并截图pageChromiumPage()page.get(http://www.ccgp.gov.cn/cggg/dfgg/zbgg/202607/t20260716_26951272.htm)# 截图只截可见表格区域已修复 NoRectErrorscreenshot_table(page,table_screenshot.png)page.quit()# 2. 用视觉模型提取prompt请从这张表格截图中提取所有数据。 要求 1. 返回 JSON 数组每行一个对象 2. 字段名使用表格的表头 3. 合并单元格的内容填到对应的每一行 4. 如果有子表格展开到同一层级 5. 只返回 JSON不要其他内容 示例输出格式 [ {序号: 1, 项目名称: 智慧城市项目, 预算_万元: 5000, 负责人: 张三}, {序号: 2, 项目名称: 数据平台项目, 预算_万元: 3000, 负责人: 李四} ]print(正在用视觉模型分析表格...)dataextract_table_from_image(table_screenshot.png,prompt)print(f\n提取到{len(data)}条数据)print(-*60)foritemindata:print(json.dumps(item,ensure_asciiFalse))# 3. 保存importpandasaspd dfpd.DataFrame(data)df.to_csv(extracted_table.csv,indexFalse,encodingutf-8-sig)print(f\n已保存到 extracted_table.csv)if__name____main__:main()运行结果示例正在用视觉模型分析表格... 提取到 1 条数据 ------------------------------------------------------------ {供应商名称: 甘肃禾木物业有限责任公司, 供应商地址: 甘肃省张掖市山丹县南大街16号, 中标金额: 2627700.00, 评审得分: 82.19} 已保存到 extracted_table.csv四、视觉模型 vs 文本模型两种方法各有优劣不是替代关系维度文本模型处理 HTML视觉模型处理截图速度快文本传输慢图片传输 理解成本低文本 token 少高图片 token 多准确率高数据结构清晰时中高偶尔识别错误适用场景结构化的 HTML复杂排版、图片数据、Canvas抗改版中改 HTML 结构可能失效高只要视觉上没变就不影响什么时候用视觉模型HTML 结构极度复杂文本模型搞不定数据在图片里价格标签、二维码、图表Canvas渲染的内容ECharts图表、地图需要 OCR 的场景扫描件、PDF 截图页面频繁改版你不想每次都改解析代码什么时候用文本模型HTML 结构规整选择器好写数据量大需要考虑成本和速度批量处理几千条数据最佳实践先用文本不行再视觉defsmart_extract(url,prompt_template):智能提取先尝试文本模型失败再上视觉模型# 1. 先尝试直接获取 HTML 文本模型try:responserequests.get(url,headersheaders)htmlresponse.text# 用文本模型提取dataextract_with_text_model(html,prompt_template)ifdataandlen(data)0:print(文本模型提取成功)returndataexcept:pass# 2. 文本模型搞不定用视觉模型print(文本模型提取失败切换到视觉模型...)pageChromiumPage()page.get(url)page.get_screenshot(pathtemp_screenshot.png)page.quit()dataextract_with_vision_model(temp_screenshot.png,prompt_template)print(视觉模型提取完成)returndata五、更多应用场景1. 提取图表数据prompt这张图片包含一个柱状图/折线图。 请提取图表中的所有数据点返回 JSON 数组。 格式[{label: 类别名, value: 数值}] 如果有多个系列每个系列分别提取。2. 提取图片中的价格prompt这张图片是商品列表页的截图。 请提取每个商品的名称和价格返回 JSON 数组。 格式[{name: 商品名, price: 数字, unit: 单位}] 注意识别图片中的价格标签。3. 提取地图标注prompt这张图片是一张地图上面标注了一些位置点。 请提取所有标注点的信息返回 JSON 数组。 格式[{name: 地点名, description: 描述如果有}]4. 提取 PDF 扫描件# 先把 PDF 转成图片再用视觉模型提取frompdf2imageimportconvert_from_path imagesconvert_from_path(scanned_document.pdf)fori,imginenumerate(images):img.save(fpage_{i}.png)dataextract_with_vision_model(fpage_{i}.png,prompt)六、提高视觉模型准确率的技巧1. 截图要清晰# 放大页面再截图提高清晰度page.run_js(document.body.style.zoom 1.5)time.sleep(1)page.get_screenshot(pathzoomed_screenshot.png)2. 只截需要的部分# 不要全屏截图只截目标区域# 复用上面的 screenshot_table() 函数自动跳过隐藏表格screenshot_table(page,target.png)3. Prompt 要具体# 模糊的 prompt不好prompt提取表格数据# 具体的 prompt好prompt提取图片中的表格数据 - 第一列是序号整数 - 第二列是项目名称字符串 - 第三列是金额数字单位万元 - 第四列是状态字符串 返回 JSON 数组只返回 JSON。4. 大图分段处理defsplit_and_extract(image_path,rows_per_chunk20):大表格分段截图提取fromPILimportImage imgImage.open(image_path)width,heightimg.size# 估算每段高度根据行高row_height40# 每行大约 40 像素chunk_heightrows_per_chunk*row_height100# 加上表头all_data[]forstart_yinrange(0,height,chunk_height-100):# 重叠100像素保证不丢行# 裁剪end_ymin(start_ychunk_height,height)chunkimg.crop((0,start_y,width,end_y))chunk_pathfchunk_{start_y}.pngchunk.save(chunk_path)# 提取dataextract_with_vision_model(chunk_path,prompt)all_data.extend(data)# 去重重叠部分可能有重复数据# ...returnall_data 本篇成本透明栏项目数值API 调用次数~5-20 次取决于页面数消耗 Token约 5-20 万 tokens图片 token 较多成本¥0GLM-4V-Flash 免费额度内视觉模型的图片 token 消耗比文本高但免费额度一般够用。练手改造题改造 1基础打开一个包含复杂表格的网站比如统计局数据页用DrissionPage截图然后用视觉模型提取表格数据。对比你手动看页面和 AI 提取的结果。改造 2进阶找一个包含ECharts图表的网页截图后用视觉模型提取图表的数据点。尝试还原出原始数据。下期预告Day 14 · 实战数据采集全流程 Pipeline前面学的东西要串起来了。Day 14 从零搭建一个完整的数据采集系统——目标电商商品价格监控。包含分析页面、编写爬虫、数据存储、AI 清洗、输出报告一条龙走完。 资源与工具智谱 GLM-4V-Flash视觉模型https://open.bigmodel.cn/DrissionPage 文档https://g1879823.gitlab.io/DrissionPage/本专栏配套代码CSDN 下载区每篇更新梅雅达编程笔记专注 Python AI 实战教程提供数据采集与自动化定制服务往期回顾Day 01 · 爬虫能干啥不能干啥Day 02 · 环境搭建与第一个爬虫Day 03 · 列表页抓取批量拿数据Day 04 · 详情页 翻页从一条到一百条Day 05 · Ajax 请求拦截抓看不到的数据Day 06 · 浏览器自动化DrissionPage 实战Day 07 · Cookie 与 Session处理登录状态Day 08 · 反爬对策Headers 限速 代理Day 09 · 存成文件CSV / Excel / JSONDay 10 · 存进数据库SQLite 从零上手Day 11 · 用 AI 替代正则智能提取结构化数据Day 12 · AI 数据清洗脏数据一键变干净专栏「AI Python 系列」 第 03 栏 ·AIPython 爬虫实战「AI Python 系列」第 01 栏 ·AI办公自动化「AI Python 系列」第 02 栏 ·AI数据可视化「AI Python 系列」第 05 栏 · AI Agent实战资源领取关注作者获取本栏完整代码和数据集原创声明本文为梅雅达编程笔记原创作品未经允许不得转载。