网页内容提取与摘要:从 HTML 到核心信息

FreeGuideOnline 最新 2026-06-23

1. 网页内容提取与摘要概述

在海量信息过载的时代,快速从网页中获取核心观点是一项必备技能。本教程将系统性地拆解 “HTML到你手中的摘要” 这一完整技术链路。你将学会如何绕过广告、导航栏等噪音,精准抓取正文内容,并利用算法自动生成简洁、连贯的摘要。

无论你是想构建自己的新闻聚合器、监控竞品动态,还是单纯想提升信息处理效率,掌握这两项技术都能为你打下坚实基础。我们将从最基础的HTML解析开始,逐步过渡到清洗规则和智能摘要算法,并提供可直接运行的Python代码示例。

2. 环境准备与核心库

开始之前,请确保你的Python版本 ≥ 3.7。本教程主要依赖以下三个库:

库名称 用途 安装命令
requests 发送HTTP请求,获取网页原始HTML pip install requests
beautifulsoup4 解析HTML文档,精准提取标签内容 pip install beautifulsoup4
sumy 一站式实现多种自动摘要算法 pip install sumy

此外,中文处理还需额外安装 jieba 分词库(pip install jieba),因为中文摘要依赖准确的分词。建议在虚拟环境中进行安装,避免依赖冲突。

3. 获取与解析完整的HTML结构

3.1 发送请求并获取页面内容

网页内容提取的第一步永远是下载HTML源码。使用requests库模拟浏览器访问,并处理可能出现的编码和异常。

import requests

url = "https://example.com/news/article"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}

try:
    # 设置超时防止假死
    response = requests.get(url, headers=headers, timeout=10)
    response.encoding = response.apparent_encoding  # 自动识别编码
    html_content = response.text
    print("页面获取成功,长度:", len(html_content))
except requests.exceptions.RequestException as e:
    print(f"请求失败: {e}")

关键点apparent_encoding 能较准确地判断中文编码,避免乱码。在实际项目中,还应加入重试机制和针对反爬的Cookie/Session管理。

3.2 使用BeautifulSoup构建解析树

拿到HTML字符串后,将其转换为可导航的文档树对象。推荐使用内置的 lxml 解析器,速度快且容错性强。

from bs4 import BeautifulSoup

soup = BeautifulSoup(html_content, 'lxml')
# 输出页面的标题以验证解析是否正常
print("页面标题:", soup.title.string if soup.title else "无标题")

此时,整个HTML已被结构化。你可以通过标签名、CSS选择器或属性进行遍历,这正是我们下一步提取正文的基础。

4. 正文提取:从噪音中分离核心信息

网页中充斥着导航、广告、侧边栏等“锅炉板”内容。有效的提取策略通常从最可能的容器入手。

4.1 基于常见标签与模式定位

现代文章网站多采用<article><main>标签,或具有特定class/id<div>包裹正文。以下是一个分步定位的通用范例:

# 策略1: 优先查找语义化标签
article_body = soup.find('article')
if not article_body:
    # 策略2: 查找常见类名组合
    article_body = soup.find('div', class_=['article-content', 'post-body', 'entry-content'])

if not article_body:
    # 策略3: 若仍为空,降级为body => 风险在于噪音较多
    article_body = soup.body

# 在定位到的容器中提取所有段落文本
paragraphs = article_body.find_all(['p', 'h2', 'h3', 'li'])

4.2 清洗提取到的文本数据

提取到的段落列表仍需清洗,去除残留标签、空行和无用符号。

import re

clean_text = []
for tag in paragraphs:
    text = tag.get_text(separator=' ', strip=True)
    # 去除非中断空格、多余空白
    text = re.sub(r'\s+', ' ', text)
    # 过滤极短碎片(通常是按钮文字或广告残留)
    if len(text) > 10:
        clean_text.append(text)

full_text = '\n'.join(clean_text)
print("提取正文预览:\n", full_text[:500])

对于JavaScript动态加载的内容,上述静态解析会失效,此时需引入 seleniumplaywright 进行渲染后再抓取。本教程聚焦于静态页面,动态渲染将在高级篇单独介绍。

5. 自动摘要生成:让机器提炼核心

获得干净正文后,即可进入摘要生成环节。算法主要分两大类:抽取式(从原文挑选关键句)和生成式(理解后重新组织语言)。抽取式速度快、不易产生语法错误,更适合工程落地,也是本教程焦点。

5.1 抽取式摘要的核心思想

抽取式摘要通过计算句子重要性得分,选取得分最高的若干句子组成摘要。常用算法包括:

  • TextRank:基于图排序模型,将句子视为节点,句子间相似度为边权重,迭代计算排名。无需事先训练语料。
  • LexRank:与TextRank类似,但在计算相似度时使用TF-IDF余弦相似度,并用阈值构建图。
  • LSA (潜在语义分析):对词频矩阵进行奇异值分解,提取主成分,每个句子在主成分上的投影向量长度即为权重。

5.2 使用Sumy实现多算法摘要

sumy库封装了主流抽取式算法,并提供统一接口。以下示例展示如何用TextRank生成中文摘要。

from sumy.parsers.plaintext import PlaintextParser
from sumy.nlp.tokenizers import Tokenizer
from sumy.summarizers.text_rank import TextRankSummarizer
from sumy.nlp.stemmers import Stemmer
from sumy.utils import get_stop_words
import jieba

# 1. 自定义中文分词器,Sumy默认仅支持英文
class ChineseTokenizer(Tokenizer):
    def to_sentences(self, text):
        sentences = text.replace('!', '。').replace('?', '?').split('。')
        return [s.strip() + '。' for s in sentences if len(s.strip()) > 5]
    
    def to_words(self, sentence):
        return jieba.lcut(sentence)

# 2. 构建Parser
parser = PlaintextParser.from_string(full_text, ChineseTokenizer())
# 3. 初始化摘要器(可选LSA、LexRank等)
summarizer = TextRankSummarizer()
summarizer.stop_words = get_stop_words('chinese')  # 需预载中文停用词

# 4. 生成摘要,数量为原文句子数的20%
sentence_count = max(1, int(len(parser.document.sentences) * 0.2))
summary = summarizer(parser.document, sentence_count)

print("---------- 自动摘要 ----------")
for sentence in summary:
    print(sentence)

性能调优:若摘要句子间不连贯,可尝试结合**MMR(最大边际相关性)**算法,在重要性基础上增加多样性惩罚,避免选出含义重复的句子。

5.3 提高摘要质量的实用技巧

  • 句子位置加权:首段和尾段往往包含结论,可人为提升这些句子的初始得分。
  • 停用词与词性过滤:在构建句子向量时剔除“的”“是”等虚词,仅保留名词、动词,增强语义区分度。
  • 后处理排序:输出摘要时按句子在原文中的出现顺序排列,而非得分高低,可极大改善可读性。

6. 端到端实战:构建一个网页摘要小工具

将前面的步骤整合为一个可复用的函数,输入URL,返回核心摘要。

import requests
from bs4 import BeautifulSoup
import re
from sumy.parsers.plaintext import PlaintextParser
from sumy.summarizers.lsa import LsaSummarizer
from sumy.nlp.tokenizers import Tokenizer
import jieba

class ChineseTokenizer(Tokenizer):
    # ... 同上定义,此处省略以节省篇幅 ...

def fetch_and_summarize(target_url, summary_ratio=0.3):
    # 1. 获取HTML
    headers = {"User-Agent": "Mozilla/5.0"}
    resp = requests.get(target_url, headers=headers, timeout=15)
    resp.encoding = resp.apparent_encoding
    soup = BeautifulSoup(resp.text, 'lxml')
    
    # 2. 提取正文
    content_block = soup.find('article') or soup.find('div', class_='content') or soup.body
    paragraphs = content_block.find_all(['p', 'h2', 'h3', 'li'])
    clean = []
    for p in paragraphs:
        t = re.sub(r'\s+', ' ', p.get_text()).strip()
        if len(t) > 15:
            clean.append(t)
    text = '。'.join(clean)  # 句子拼接
    
    # 3. 生成摘要
    parser = PlaintextParser.from_string(text, ChineseTokenizer())
    summarizer = LsaSummarizer()
    sentence_num = max(1, int(len(parser.document.sentences) * summary_ratio))
    summary_sents = summarizer(parser.document, sentence_num)
    
    # 4. 输出按原文顺序排列的摘要
    original_order = sorted(summary_sents, key=lambda s: text.index(str(s)))
    return '\n'.join(str(s) for s in original_order)

# 使用示例
print(fetch_and_summarize("https://example.cn/article/123"))

7. 常见问题与进阶方向

Q: 提取的内容包含大量JavaScript注释或JSON数据? 直接用beautifulsoup抓取时会遗漏文本。建议使用requests-html或抓包找到数据接口,直接请求JSON。

Q: 生成的摘要不通顺怎么办? 抽取式摘要的天然缺陷是无法保证句间平滑过渡。可考虑在输出前插入少量连词,或采用生成式模型(如T5、BART)做文本重写,但生成式模型部署成本较高,且可能引入“幻觉”。

Q: 如何评估摘要质量? 自动化指标可使用ROUGE(Recall-Oriented Understudy for Gisting Evaluation)与人工摘要对比,但实际项目更依赖人工抽检。重点关注覆盖度简洁性的平衡。

进阶学习路径

  • 嵌入向量(如Sentence-BERT)计算句子语义相似度,替代传统TF-IDF。
  • 结合标题、首段等结构特征进行有监督摘要排名。
  • 使用大型语言模型API(如GPT系列)通过提示词直接生成摘要,效果惊艳但成本需考量。

8. 总结

本教程从零开始,完整走通了“HTML下载→正文提取→文本清洗→自动摘要”的全流程。你已掌握利用BeautifulSoup精准定位内容块、通过规则去除噪音、以及使用sumy的抽取式算法生成摘要的方法。这些技术是构建RSS监控、舆情分析、个人知识库等应用的基石。

开始动手吧:先选一个你常访问的资讯网站,用今天的代码跑出第一份自动摘要,再根据页面结构微调提取规则。持续实践,你提取的信息纯度将越来越高。