ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

本地解析HTML:提取商品ID与生成9:16封面的实践指南

本地解析HTML:提取商品ID与生成9:16封面的实践指南 在电商爆款素材整理里一个很常见的需求是把商品页面里的商品 ID、主图原图批量提取出来再统一生成 9:16 的封面图。很多人一上来就搜爬虫教程但如果你仔细分析会发现真正要处理的页面并不是要靠程序去自动抓取的而是浏览器里已经正常打开过的页面。把页面保存到本地后再做解析整个流程不涉及自动请求第三方服务器这就是“本地解析非爬虫”的含义。这篇文章围绕多多平台爆款商品页的素材整理场景把完整链路拆开讲从手动保存 HTML到用正则和 BeautifulSoup 提取商品 ID到还原原图 URL 并批量下载最后用 Pillow 或 Playwright 生成 1080x1920 的 9:16 精准截图。文中的代码可以直接复制到本地跑通实际页面结构有差异时再调整选择器和参数即可。1. 先理解本地解析不是爬虫而是处理已打开的页面1.1 本地解析和网络爬虫的边界网络爬虫的定义是按照一定规则由程序主动向目标服务器发起 HTTP 请求批量获取网页并抽取数据的自动化程序。它的关键特征是“主动请求”程序拿着 URL 列表去访问服务器因此会带来访问频率、服务器压力、反爬策略等一系列问题。本地解析则完全不同。它的输入是用户在自己浏览器里已经打开过的页面通过“另存为”或复制渲染后 DOM 的方式保存成本地 HTML 文件。解析程序只读取本地文件不主动去请求目标网站的 URL。也就是说网络请求这一步发生在浏览器手工操作阶段之后的分析和提取全部在本地完成。很多人搜爬虫教程实际上要解决的需求只是把已经打开的页面里的信息整理出来。这类需求用本地解析更合适不需要处理验证码、不需要担心 IP 被封、不依赖网络波动解析过程反复运行都不会给对方服务器造成压力。对比维度网络爬虫本地解析输入URL 列表本地 HTML 文件请求方式程序自动发起 HTTP 请求浏览器手动打开后保存触发频率可能高频访问目标服务器不产生额外网络请求合规风险较高容易被平台认定为爬虫相对低但仍需遵守数据使用边界稳定性受反爬、验证码、封 IP 影响稳定不受对方服务器限制1.2 这个工具要解决的三个功能点第一个功能点是批量提取商品 ID。商品 ID 是后续做商品比对、库存核对、素材关联的关键字段它在页面里可能出现在链接参数、元素 data 属性、内嵌 JSON 数据等多个位置人工一个个复制效率很低。第二个功能点是提取原图 URL。页面里展示给用户看的图片往往是 CDN 动态压缩后的缩略图URL 里带了一堆尺寸和处理参数。直接保存缩略图生成封面时画质不够。因此需要把缩略图 URL 还原成原图 URL再批量下载。第三个功能点是生成 9:16 精准截图。现在很多电商素材要用于短视频平台和内容卡片宽高比要求 9:16标准尺寸是 1080x1920。直接拿商品图缩放会变形或出现黑边需要用图像处理方式做背景填充或页面截图。1.3 整体流程与技术选型完整流程可以拆成六步浏览器打开商品页面手动保存 HTML 文件到 pages 目录本地脚本读取所有 HTML用正则或 DOM 解析提取商品 ID 和图片 URL下载原图到 images 目录最后生成 9:16 封面到 covers 目录。技术选型使用 Python 3原因是生态成熟、代码量少。解析层用 BeautifulSoup 加 lxmlBeautifulSoup 容错性好lxml 解析速度快图片下载用 requests处理简单直接图像合成用 Pillow能满足大部分封面生成需求如果需要对页面本身截图则用 Playwright 做无头浏览器渲染。2. 环境准备与页面素材获取依赖、目录和手动保存2.1 Python 版本与依赖安装建议使用 Python 3.9 及以上版本。先创建虚拟环境避免依赖冲突python -m venv .venvWindows 下激活虚拟环境.venv\Scripts\activatemacOS 或 Linux 下激活source .venv/bin/activate安装基础依赖pip install beautifulsoup4 lxml requests pillow如果后面需要做页面截图再安装 Playwrightpip install playwright playwright install chromium各依赖的用途如下表所示包版本建议用途beautifulsoup44.12HTML 解析与 DOM 遍历lxml4.9底层解析器性能更好requests2.31下载原图pillow10.x图像缩放、模糊、合成playwright1.x无头浏览器页面截图安装完成后可以用下面的命令确认环境正常python -c import bs4, lxml, requests, PIL; print(ok)2.2 项目目录结构规划建议按输入、中间产物、输出分开存放避免处理大量文件时目录混乱product_parser/ ├── pages/ # 手动保存的 HTML 文件 ├── images/ # 下载的原图 ├── covers/ # 生成的 9:16 封面图 ├── output/ # 导出的表格和日志 └── parse_products.py创建目录mkdir pages images covers output代码脚本 parse_products.py 放在项目根目录页面文件全部放进 pages后续脚本只扫描这个目录逻辑清晰。2.3 手动保存 HTML 的正确姿势在浏览器中打开商品页面后在页面空白处右键选择“另存为”保存类型可以选“网页仅 HTML”或“网页全部”。只要 HTML 里包含商品 ID 和图片地址选“仅 HTML”就够用如果图片是懒加载模式真实地址往往在>import re def extract_ids_by_regex(html: str) - set: 从 HTML 文本中提取商品 ID返回去重后的集合 patterns [ r(?:goods_id|goodsId|productId|item_id)[\: ](\d{10,20}), rgoods_id[/](\d{10,20}), rgoodsId[\]?\s*:\s*[\]?(\d{10,20}), ] ids set() for pattern in patterns: ids.update(re.findall(pattern, html)) return ids第一行正则里的[\: ]表示属性名和值之间可以有冒号、引号、等号或空格这样能兼容goods_id123、goodsId:123、goods_id: 123多种写法。第二、第三行是针对 URL 路径形式和 JSON 键值形式的补充。3.3 用 BeautifulSoup 按 DOM 结构提取正则的缺点是理解起来不直观而且如果 HTML 结构不规范匹配容易出错。DOM 方式更适合处理嵌套结构也更利于后续维护from bs4 import BeautifulSoup def extract_ids_by_dom(html: str) - set: 根据 DOM 结构和元素属性提取商品 ID soup BeautifulSoup(html, lxml) ids set() # 从 a 标签的 href 参数中提取 for a in soup.find_all(a, hrefTrue): href a[href] if goods in href.lower() or product in href.lower(): match re.search(r(?:goods_id|goodsId|productId|item_id)(\d{10,20}), href) if match: ids.add(match.group(1)) # 从 data 属性中提取 for selector in [[data-goods-id], [data-goods_id], [data-product-id]]: for elem in soup.select(selector): value elem.get(data-goods-id) or elem.get(data-goods_id) or elem.get(data-product-id) if value and value.isdigit() and len(value) 10: ids.add(value) return ids这段代码里有两个值得注意的点。第一遍历 a 标签时先判断链接里是否包含 goods 或 product 关键字再提取数字能避免把站内其他链接的参数也捞进来。第二data 属性选择器写全了多种命名风格实际页面用下划线还是驼峰都能命中。3.4 去重、校验与导出 CSV一个 HTML 文件里可能多次出现同一个商品 ID多个 HTML 文件之间也可能重复。把结果放进 set 集合里天然去重。导出 CSV 时用 utf-8-sig 编码是为了让 Excel 直接打开不乱码import csv from pathlib import Path def load_html(file_path: Path) - str: 读取 HTML 文件按 UTF-8、GBK 顺序尝试解码 data file_path.read_bytes() for encoding in (utf-8, gbk, gb18030): try: return data.decode(encoding) except UnicodeDecodeError: continue return data.decode(utf-8, errorsignore) def main(): all_ids set() for html_file in Path(pages).glob(*.html): html load_html(html_file) ids extract_ids_by_regex(html) | extract_ids_by_dom(html) print(f{html_file.name}: {len(ids)} 个商品 ID) all_ids.update(ids) print(f总计: {len(all_ids)} 个去重后的商品 ID) with open(output/product_ids.csv, w, newline, encodingutf-8-sig) as f: writer csv.writer(f) writer.writerow([商品 ID]) for pid in sorted(all_ids): writer.writerow([pid]) if __name__ __main__: main()这里用两个提取函数取并集正则能扫到 script 里的 JSONDOM 能处理结构清晰的标签属性两者互补。运行后检查 output/product_ids.csv如果一行一个 ID、数量合理说明解析成功。4. 原图 URL 还原与批量下载从缩略图找回高清图4.1 页面里的图片为什么不是原图电商平台的图片 URL 通常由 CDN 动态生成。页面为了加载速度会把图片压缩成指定尺寸URL 里会带?x-oss-processimage/resize,w_400这样的处理参数或者文件名里带_400x400之类的尺寸后缀。如果直接把这种图保存下来画质偏低放到 9:16 封面里会明显发糊。原图还原的本质是理解 CDN 的 URL 规则哪些参数和尺寸后缀是缩略图特有的去掉之后是否还能访问到原始图片。不同平台的规则不一样但思路是通用的。4.2 还原原图 URL 的通用规律from urllib
返回列表