尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Python Show-Me-the-Code 第 0008 题:用 TaoToken 统一 Key 提取 HTML 正文内容
1. 从一道老题说起HTML 正文提取到底难在哪如果你刷过 Python 的 Show-Me-the-Code 系列第 0008 题大概率让你卡过壳给一个 HTML 文件把里面的正文抠出来。题目描述只有一句话但真动手写才发现网页里塞满了导航栏、侧边栏、评论区、广告位、页脚版权正文往往只占整个 DOM 的百分之十几。用正则去匹配p标签遇到嵌套结构直接崩。用 BeautifulSoup 一把梭soup.get_text()结果把菜单和推荐阅读全带出来了读起来像一锅乱炖。这道题的核心检索词就是Python HTML 正文内容提取它要解决的问题是从一堆标签和噪声里稳定地还原出人眼看到的那段文章。适合谁写爬虫做数据清洗的、做 RAG 需要把网页转成干净文本喂给模型的、以及想批量归档博客文章的人。我试过纯手写规则维护成本高得离谱换个站点就得重调后来转向「解析库 正文算法 模型兜底」的组合才把链路跑顺。这篇文章不讲空理论直接给你一条能复制的完整链路requests 抓页面、BeautifulSoup 做初步清洗、正文提取算法去噪、最后把模型调用 endpoint 统一改到 TaoToken 管理 Key用一组样例页面验证输出是否干净可读。每一步都有代码和参数你可以边看边跑。先说清楚一个认知正文提取没有银弹。不同站点结构差异巨大纯算法方案在新闻站表现好在论坛或文档站可能翻车。所以我的策略是「算法打底 模型补刀」——先用轻量算法拿到 80% 的干净文本剩下结构诡异的页面再交给模型做二次抽取。而模型调用这块如果每个项目都散落着不同的 Key管理起来就是灾难这也是我把 endpoint 统一到 TaoToken 的原因。2. 前置准备requests BeautifulSoup 环境与 TaoToken Key 统一管理动手之前先把环境搭好。正文提取这条链路依赖两个库requests负责发请求拿 HTMLbeautifulsoup4负责解析 DOM再配一个lxml解析器提速。安装命令很直接pip install requests beautifulsoup4 lxml如果你还想用现成的正文提取库做对照可以顺手装trafilatura它在多语言新闻正文上表现稳定后面我会拿它和手写方案对比。安装pip install trafilatura环境好了接下来是 Key 管理。为什么要在正文提取里提模型调用因为纯算法搞不定的页面你需要一个模型来做「这段文本是不是正文」的判断或直接抽取。问题在于如果你同时用 OpenAI、Claude、国产模型Key 散落在各个脚本和环境变量里换台机器就得重新配一遍团队协作更是互相覆盖。我的做法是把所有模型调用统一走一个 endpointKey 只维护一份。TaoToken 在这里扮演的就是统一入口的角色。它的 API 地址是https://taotoken.net/api兼容 OpenAI 的接口格式意味着你原来用openaiSDK 写的代码只需要改base_url和api_key两个参数其余逻辑不动。先去控制台创建一个 Key控制台入口https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewriteAPI Keys 管理https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite创建完 Key 之后把它写进环境变量别硬编码在脚本里export TAOTOKEN_API_KEYsk-你的key export TAOTOKEN_BASE_URLhttps://taotoken.net/api这样你的正文提取脚本里模型调用部分就只认这两个变量。后面无论换模型还是加新模型都只改配置不改代码。对于正文提取这种需要反复调试 prompt 的场景统一 Key 能省掉大量「这个 Key 是哪个账号的」的排查时间。注意Key 属于敏感凭证不要提交到 Git 仓库。建议用.env文件配合python-dotenv加载或者直接用系统环境变量。3. 可复制配置requests 抓取 BeautifulSoup 清洗 模型 endpoint 片段这一节给你可以直接抄的配置。先看抓取和清洗部分。核心思路是requests 拿到 HTML 后先用 BeautifulSoup 干掉 script、style、nav、footer 这些明显不是正文的标签再提取候选文本块。import os import requests from bs4 import BeautifulSoup HEADERS { User-Agent: ( Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0 Safari/537.36 ) } NOISE_TAGS [script, style, nav, footer, header, aside, form, iframe, noscript] def fetch_html(url: str, timeout: int 15) - str: resp requests.get(url, headersHEADERS, timeouttimeout) resp.raise_for_status() resp.encoding resp.apparent_encoding return resp.text def clean_soup(html: str) - BeautifulSoup: soup BeautifulSoup(html, lxml) for tag in soup(NOISE_TAGS): tag.decompose() return soup上面这段是基础。真正决定正文质量的是「候选块打分」。我用的简化版逻辑是遍历所有p和div按文本长度和标点密度打分取分数最高的容器作为正文根节点。完整函数import re def score_block(text: str) - float: if not text: return 0.0 length len(text) punct len(re.findall(r[。,.!?;:], text)) link_density text.count(http) / max(length, 1) return length * 0.5 punct * 2 - link_density * 100 def extract_main_text(soup: BeautifulSoup) - str: candidates soup.find_all([p, div, article, section]) best, best_score None, 0.0 for node in candidates: text node.get_text(stripTrue) s score_block(text) if s best_score: best, best_score node, s if best is None: return soup.get_text(\n, stripTrue) return best.get_text(\n, stripTrue)接下来是模型 endpoint 配置。当算法提取结果不理想时把候选文本丢给模型做二次判断。这里用 OpenAI 兼容格式base_url指向 TaoTokenfrom openai import OpenAI client OpenAI( api_keyos.environ[TAOTOKEN_API_KEY], base_urlos.environ.get(TAOTOKEN_BASE_URL, https://taotoken.net/api), ) MODEL_ID gpt-4o-mini # 按需替换为控制台可用的模型 ID def refine_with_model(raw_text: str) - str: prompt ( 下面是从网页提取的候选文本请只保留文章正文 去掉导航、广告、评论、版权等噪声直接输出正文\n\n raw_text[:6000] ) resp client.chat.completions.create( modelMODEL_ID, messages[{role: user, content: prompt}], temperature0, ) return resp.choices[0].message.content.strip()如果你更习惯用配置文件管理可以写一个settings.toml[taotoken] base_url https://taotoken.net/api api_key_env TAOTOKEN_API_KEY model_id gpt-4o-mini三件套齐了Base URL 是https://taotoken.net/apiKey 从环境变量读Model ID 按控制台可用列表填。这样无论你后面接 Claude Code 还是别的工具配置结构都一致。4. 验证请求跑一组样例页面看正文是否干净可读配置写完必须验证。我准备了三个不同类型的页面一篇技术博客、一个新闻页、一个文档页。跑下面这段主流程def pipeline(url: str, use_model: bool False) - str: html fetch_html(url) soup clean_soup(html) text extract_main_text(soup) if use_model: text refine_with_model(text) return text if __name__ __main__: url https://example.com/blog/some-post result pipeline(url, use_modelFalse) print(result[:800])实测下来技术博客类页面用纯算法就能拿到比较干净的结果正文段落完整导航和页脚被decompose掉了。新闻页因为正文集中在article里打分逻辑能准确命中。文档页稍微麻烦因为侧边栏目录和正文都是长文本链接密度特征帮了忙——目录里链接多得分被压低正文胜出。如果你想看模型二次抽取的效果把use_modelTrue打开对比两次输出。模型版的好处是能处理「正文里混了推荐阅读」这种算法难判断的情况代价是多一次网络请求和 token 消耗。我的建议是批量任务先用算法跑一遍把明显异常的页面文本过短或过长挑出来只对这些页面调模型成本可控。验证时重点看三个指标正文首段是否完整、有没有混入「相关阅读」「版权声明」、段落之间是否保留了换行。如果换行丢了检查get_text的分隔符参数用\n而不是默认空串。5. 常见报错排查401、local proxy failed、reading choices 与 OAuth链路跑起来后报错基本集中在这几类我按真实遇到的顺序列一下。401 Unauthorized最常见。要么 Key 没设进环境变量要么base_url写错了。检查echo $TAOTOKEN_API_KEY是否有值再确认base_url是https://taotoken.net/api而不是带多余路径。注意有些 SDK 会自动拼接/v1如果报 404 而不是 401多半是路径重复了。local proxy failed / connection error这类通常是本机网络环境或代理配置导致的连接失败。先确认你的请求能正常访问外网再检查requests是否被系统代理干扰。可以在代码里显式传proxies{http: None, https: None}排除干扰或者检查环境变量HTTP_PROXY是否指向了失效地址。reading choices of undefined这个报错说明返回体结构和你预期的不一样。常见原因是模型 ID 填错服务端返回了错误对象而不是标准的choices数组。打印完整resp看error字段确认MODEL_ID在控制台可用列表里。另外如果用了流式但没处理 chunk也会出现类似问题。OAuth / 认证失败如果你在 Claude Code 或类似工具里配置注意区分 API Key 认证和 OAuth 认证。走 API Key 时Base URL 填https://taotoken.net/apiKey 填控制台生成的sk-开头字符串。OAuth 流程和 API Key 是两套东西别混用。Claude Code 的接入文档在这里https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite排查时养成习惯先单独用 curl 测通接口再回到 Python 脚本。curl 命令curl https://taotoken.net/api/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d {model:gpt-4o-mini,messages:[{role:user,content:ping}]}curl 通了脚本不通问题就在代码curl 也不通问题在 Key 或网络配置。6. 把链路用起来从单页提取到批量归档单页跑通只是开始。实际场景里你面对的是几百上千个 URL需要批量处理、去重、存盘。我的做法是把上面的pipeline包一层加并发和重试from concurrent.futures import ThreadPoolExecutor import time def safe_pipeline(url: str, retries: int 3) - str: for i in range(retries): try: return pipeline(url, use_modelFalse) except Exception as e: if i retries - 1: return f[FAILED] {url}: {e} time.sleep(1.5 * (i 1)) urls [https://example.com/a, https://example.com/b] with ThreadPoolExecutor(max_workers5) as pool: results list(pool.map(safe_pipeline, urls))并发数别开太大5 到 8 比较稳避免被目标站限流。存盘时按 URL 的 hash 命名方便断点续跑。如果你要把提取结果喂给模型做摘要或问答直接复用第 3 节的 client把refine_with_model换成你的业务 prompt 即可。长期做编码和 Agent 任务的话可以考虑 Coding Plan把模型调用额度集中管理https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite想先验证模型输出质量用模型对话页面快速试 prompthttps://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite最后给一个实用技巧正文提取的质量七分靠清洗三分靠算法。与其花时间调打分公式不如先把NOISE_TAGS列表按目标站点补全把评论区和推荐模块的 class 名加进黑名单。这一步的收益比换任何库都大。
RELATED

相关推荐

OpenCvSharp条码识别实战:C#项目高效解码指南

OpenCvSharp条码识别实战:C#项目高效解码指南

简介:本资源面向需要在C#项目中实现条形码识别的开发者,尤其是使用OpenCVSharp却受限于其默认不支持条码读取功能的工程师。资源通过将OpenCV条形码模块封装为DLL,再在C#项目中引用调用的方式,打通了跨语言调用的技术路径&#xf…

📅 2026/9/29 14:00:00
WinForm心率曲线图实战:多路生命体征波形绘制与性能优化

WinForm心率曲线图实战:多路生命体征波形绘制与性能优化

简介:这是一份面向C# WinForm开发者的生命体征波形绘制示例,聚焦心率、血氧、呼吸等生理曲线在桌面端的实时呈现,适合医疗软件、健康监测类项目的初学者与中级开发者参考。资源包共53个文件,约129KB,以8个cs源码文件为…

📅 2026/9/29 14:00:00
业务迁移全流程指南:从流程拆解到避坑实践

业务迁移全流程指南:从流程拆解到避坑实践

简介:面向IT运维、架构师及云平台建设人员的业务迁移方案讲解型课件,系统梳理了业务迁移的完整链路:从迁移需求分析、目的界定,到迁移流程的四个阶段(迁移、测试验证、增量同步、业务切换),再到…

📅 2026/9/29 14:00:00
MORE NEWS

更多资讯

📰

DeepSeek 财务系统智能化方案:从本地部署到报销自动化

简介:一套DeepSeek与AI大模型驱动的财务管理智能化建设方案PPTX课件,面向企业财务管理者、数字化转型规划人员及财务信息化从业者,聚焦自动化票据处理、智能预算、现金流风控、数据决策支持、税务合规审计等核心模块。资源为1个pptx演示文稿&…

📰

NetApp FAS8300部署实战:硬件校准、四平面隔离与RAID-DP规划

简介:本资源是NetApp FAS8300企业级存储系统的官方级安装与配置实操手册,面向存储工程师、系统集成人员及中高级IT运维人员,聚焦FAS8300从开箱初始化到多协议业务交付的全流程落地。文档覆盖集群创建(含双节点加入与状态验证&…

📰

工业级缺失值填充实战:pandas/scikit-learn/statsmodels协同方案

简介:本资源是一份面向Python初学者与数据分析入门者的「数据处理之缺失值填充」实战指南,聚焦数据预处理核心环节,系统讲解缺失值成因、类型识别及六类主流填充策略的适用场景与代码实现。内容覆盖直接删除法(dropna)…

📰

企业级AI大模型数字底座:可部署、可验证的工程化实践

简介:本资源是一份面向企业数字化转型实践者的AI大模型数字底座项目设计方案,适用于具备IT基础的企业管理者、技术总监、数据科学家及IT工程师,旨在系统解决智能化决策支撑不足、业务流程自动化程度低、数据资产价值释放不充分等核心问题。文…

📰

DeepSeek-R1医疗问诊私有化部署实战:成本、提示词与避坑

简介:面向医疗行业信息化与人工智能落地团队的技术文档,聚焦 DeepSeek-R1 模型在问诊系统中实现约 90% 成本降幅的完整适配思路。文档共 23 页,先梳理在线问诊系统现状与硬件、软件、人力、数据四类成本痛点,再讲解模型的技术原理…

📰

Jev模型服务接入指南:从密钥申请到Codex配置实战

最近几天,Jev这个词突然在开发者社群里刷屏了。打开技术群、刷动态,到处是“Jev模型官网”“Jev密钥”“Jev在Codex里怎么用”这类关键词。但问了一圈,发现一个很尴尬的现象:真正能讲清楚Jev是什么的人,没几个。有人以…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬