ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

爬虫实战12:用 TaoToken 统一 Key 打通自动摘要与正文抽取流水线

爬虫实战12:用 TaoToken 统一 Key 打通自动摘要与正文抽取流水线 1. 爬虫采集之后真正难啃的是正文抽取和自动摘要做爬虫的朋友大概率都有这种体验请求发出去、HTML 拿到手看着满屏的div、script、广告位、导航栏真正想要的那几百字正文反而藏在最里面。更麻烦的是采集量一上来你不可能靠人工去读每一篇必须让程序自动把正文抽出来再顺手生成一段摘要才能进入下游的检索、分类或者推送环节。这一篇就聚焦采集之后的两个环节正文抽取和自动摘要。适合已经能跑通基础爬虫、手里有一批原始 HTML、想把它变成干净文本并批量产出摘要的开发者。我会用一个统一的 Key 把「正文抽取模型」和「摘要模型」串成一条流水线配置文件用config.toml管理从原始 HTML 一路走到摘要结果中间每一步都能单独验证。传统做法里正文抽取要么靠lxml的clean清标签要么靠 Text/Tag 比值、K-Means 聚类去猜正文块要么给核心站点写 XPath 模板。这些方法我都试过规则维护成本高换一个站点结构就失效。现在的思路更省事把清洗后的 HTML 交给模型做正文识别再把正文交给摘要模型两个环节共用一个 Key配置和调用方式统一维护成本直接降下来。下面按「问题场景 → 前置准备 → 可复制配置 → 验证请求 → 排错 → 后续动作」的顺序展开代码都能直接抄。2. 前置准备TaoToken 统一 Key 与项目骨架2.1 为什么用统一 Key 而不是每个模型一套凭证正文抽取和摘要生成本质上是两次模型调用。如果分别对接不同平台你要维护两套鉴权、两套限流、两套错误码批量跑的时候一出问题就得两头查。用 TaoToken 的好处是一个 Key 覆盖对话类模型调用正文抽取和摘要走同一个入口配置只写一份日志和重试逻辑也能复用。TaoToken 的 API 入口是https://taotoken.net/api兼容常见的对话补全调用格式。你不需要改太多代码把base_url和api_key换掉就能接上。2.2 拿 Key 和建项目先去控制台创建 API Key入口在这里控制台https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteAPI Keys 管理https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite拿到 Key 之后建一个干净的项目目录结构建议这样spider_pipeline/ ├── config.toml ├── requirements.txt ├── pipeline.py └── samples/ └── raw_article.htmlrequirements.txt里先放最基础的依赖requests lxml tomliPython 3.11 以上自带tomllib如果是低版本就用tomli读 TOML。2.3 把 Key 放进环境变量别写进代码Key 直接写进config.toml再提交到仓库是新手最容易踩的坑。正确做法是环境变量存 Key配置文件只引用变量名export TAOTOKEN_API_KEY你的KeyWindows 下用set或者系统环境变量面板设置效果一样。这样配置文件可以放心进版本库团队协作也不会泄露凭证。3. 可复制配置config.toml 骨架与统一 Key 接入3.1 config.toml 完整骨架下面这份配置把「接口地址、鉴权、正文抽取模型、摘要模型、超时重试」都收在一起改站点或者换模型只动这一处[api] base_url https://taotoken.net/api api_key_env TAOTOKEN_API_KEY timeout 60 max_retries 3 [extract] model claude-3-5-sonnet system_prompt 你是一个正文抽取器。输入是网页 HTML 或清洗后的文本 请只输出文章正文去掉导航、广告、评论、页脚、相关推荐。 不要解释不要加标题直接输出正文纯文本。 max_tokens 4096 [summary] model claude-3-5-sonnet system_prompt 你是一个摘要生成器。输入是一篇正文 请输出 3 句话以内的中文摘要覆盖核心事实不要评论不要加前缀。 max_tokens 512 [pipeline] min_body_chars 120 summary_max_chars 200几个参数说明一下。timeout给 60 秒是因为长正文抽取偶尔会慢max_retries设 3网络抖动时自动重试min_body_chars是正文长度下限抽出来太短说明可能失败直接标记异常而不是硬塞给摘要模型。3.2 读取配置与初始化客户端import os import tomli import requests def load_config(pathconfig.toml): with open(path, rb) as f: cfg tomli.load(f) cfg[api][api_key] os.environ[cfg[api][api_key_env]] return cfg def chat(cfg, model, system_prompt, user_content, max_tokens): url f{cfg[api][base_url]}/v1/chat/completions headers { Authorization: fBearer {cfg[api][api_key]}, Content-Type: application/json, } payload { model: model, max_tokens: max_tokens, messages: [ {role: system, content: system_prompt}, {role: user, content: user_content}, ], } last_err None for _ in range(cfg[api][max_retries]): try: resp requests.post( url, headersheaders, jsonpayload, timeoutcfg[api][timeout], ) resp.raise_for_status() return resp.json()[choices][0][message][content].strip() except Exception as e: last_err e raise RuntimeError(f调用失败: {last_err})这段代码是整条流水线的地基正文抽取和摘要都复用它只是传入不同的system_prompt和max_tokens。3.3 先做本地清洗再交给模型模型不是用来干粗活的。HTML 里的script、style、注释这些先用lxml清掉能省 token 也能提高抽取准确率from lxml.html import clean def preclean(html: str) - str: cleaner clean.Cleaner( styleTrue, scriptsTrue, commentsTrue, javascriptTrue, page_structureFalse, safe_attrs_onlyFalse, ) return cleaner.clean_html(html)注意page_structureFalse保留结构信息模型判断正文块时更有依据。清完之后再走模型比直接丢原始 HTML 效果好很多。4. 完整链路从原始 HTML 到正文再到摘要4.1 正文抽取函数def extract_body(cfg, html: str) - str: cleaned preclean(html) body chat( cfg, modelcfg[extract][model], system_promptcfg[extract][system_prompt], user_contentcleaned, max_tokenscfg[extract][max_tokens], ) if len(body) cfg[pipeline][min_body_chars]: raise ValueError(f正文过短可能抽取失败: {len(body)} 字) return body4.2 摘要生成函数def summarize(cfg, body: str) - str: summary chat( cfg, modelcfg[summary][model], system_promptcfg[summary][system_prompt], user_contentbody, max_tokenscfg[summary][max_tokens], ) return summary[: cfg[pipeline][summary_max_chars]]4.3 串成流水线def run_pipeline(cfg, html: str) - dict: body extract_body(cfg, html) summary summarize(cfg, body) return { body_len: len(body), body: body, summary: summary, } if __name__ __main__: cfg load_config() with open(samples/raw_article.html, encodingutf-8) as f: html f.read() result run_pipeline(cfg, html) print(正文长度:, result[body_len]) print(摘要:, result[summary])到这里一条「原始 HTML → 清洗 → 正文抽取 → 摘要生成」的链路就跑通了。批量处理时把run_pipeline放进循环或者任务队列每个 URL 独立处理失败的单条记录日志重试即可。5. 验证请求与结果比对5.1 用 curl 先验证 Key 和接口通不通在写业务代码之前先用一条最小请求确认鉴权和接口没问题curl https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: claude-3-5-sonnet, max_tokens: 128, messages: [ {role: user, content: 只回复两个字通了} ] }返回里能看到choices[0].message.content就说明 Key 和地址都对。这一步能排掉一大半「代码跑不通」的问题。5.2 结果比对动作拿一篇结构清晰的新闻页做样本跑完流水线后做三件事第一看正文长度是否落在合理区间。一篇 800 字的新闻抽出来 700 到 900 字算正常抽出来 80 字基本是失败。第二人工扫一眼正文开头和结尾确认没有混进「相关阅读」「版权声明」这类噪声。第三看摘要是否覆盖了正文的核心事实。如果摘要里出现了正文没有的信息说明模型在编需要收紧system_prompt。我一般会把这三项做成一个简单的检查脚本批量跑完之后统计失败率超过阈值就回头调 prompt 或者清洗逻辑。5.3 想直接对比不同模型效果如果你不确定哪个模型抽取更准可以开一个对话页面手动贴几段 HTML 对比输出模型对话https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite同一段 HTML 分别跑两三个模型看谁漏得少、噪声少再决定config.toml里写哪个。6. 本篇常见错排查6.1 401 或鉴权失败最常见的原因是环境变量没生效。export只在当前终端会话有效换个窗口就没了。建议写进~/.bashrc或者用.env文件配合加载库。另外检查 Key 有没有多余空格复制粘贴时很容易带上换行。6.2 正文抽取结果为空或极短先确认preclean有没有把正文一起清掉。有些页面正文写在noscript里或者依赖 JS 渲染lxml拿到的 HTML 本身就是空的。这种情况要么换渲染方式要么在采集阶段就把渲染后的 HTML 存下来。另一个原因是min_body_chars设太高把正常短文误判成失败可以适当调低。6.3 摘要出现「根据您提供的正文」这类前缀这是system_prompt约束不够。把「不要加前缀、不要解释、直接输出摘要」写得更明确必要时在 prompt 里给一个输出示例。模型很吃示例这一套。6.4 批量跑的时候频繁超时单条 60 秒超时批量并发一高就容易触发。两个方向一是降低并发数给接口留余量二是把长正文先截断到合理长度再送摘要摘要本来也不需要全文。正文抽取环节如果页面特别大可以在preclean之后再做一次长度裁剪。6.5 摘要和正文对不上如果摘要里出现正文没有的人名、数字说明模型在补全。把summary的system_prompt改成「只允许使用输入正文中出现的信息」并且把max_tokens压小减少自由发挥空间。7. 后续动作把流水线接到长期任务上单次跑通只是开始。真正做批量采集你需要考虑的是任务怎么排队、失败怎么重试、结果怎么落库、模型调用成本怎么控制。如果这条流水线要长期跑尤其是涉及编码类 Agent 或者定时任务可以了解一下 Coding Plan把调用额度和并发规划好避免跑到一半被限流打断Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite接入细节和参数说明都在文档里遇到报错先翻文档比到处问快接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite我的建议是先把config.toml里的模型和 prompt 固定下来用 20 到 50 篇样本跑一轮统计正文抽取成功率和摘要可用率达标之后再放大批量。流水线这种东西前期多花半小时调 prompt后期能省掉大量人工返工。
返回列表