深度学习在DOM解析中的应用:自动识别页面关键内容区块

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
Elasticsearch Serverless检索通用型,资源抵扣包 100CU*H
简介: 本文探讨了如何通过深度学习模型优化东方财富吧财经新闻爬虫的性能。针对网络请求、DOM解析与模型推理等瓶颈,采用代理复用、批量推理、多线程并发及模型量化等策略,将单页耗时从5秒优化至2秒,提升60%以上。代码示例涵盖代理配置、TFLite模型加载、批量预测及多线程抓取,确保高效稳定运行,为大规模数据采集提供参考。

摘要

本文介绍了如何在爬取东方财富吧(https://www.eastmoney.com)财经新闻时,利用深度学习模型对 DOM 树中的内容区块进行自动识别和过滤,并将新闻标题、时间、正文等关键信息分类存储。文章聚焦爬虫整体性能瓶颈,通过指标对比、优化策略、压测数据及改进结果,展示了从单页耗时约 5 秒优化到约 2 秒的过程,极大提升了工程效率。


一、性能瓶颈点

  1. 网络请求与代理调度
    • 每次 HTTP 请求需经由爬虫代理,存在连接与认证开销。
  2. DOM 解析与深度学习推理
    • 使用 BeautifulSoup 遍历大规模节点;
    • 对每个候选区块进行深度学习模型推理(TensorFlow/Keras),推理时间占比高。
  3. 单线程串行抓取
    • 不支持并发,无法充分利用多核 CPU 与网络带宽。

二、指标对比(优化前)

指标 单页耗时 (秒) CPU 占用 内存占用
网络请求 + 代理 1.2 5% 50 MB
DOM 解析 0.8 10% 100 MB
模型推理 (单区块) 2.5 30% 200 MB
数据存储(本地 SQLite) 0.5 5% 20 MB
总计 5.0 50% 370 MB

三、优化策略

  1. 代理连接复用
    • 启用 requests.Session 并开启 HTTP Keep-Alive,减少握手耗时;
  2. 批量深度学习推理
    • 将多个候选区块合并为批次(Batch)输入模型,一次性完成推理,减少启动开销;
  3. 多线程并发抓取
    • 采用 concurrent.futures.ThreadPoolExecutor 实现多线程并发请求与解析,提高吞吐量;
  4. 模型量化与 TensorFlow Lite
    • 将 Keras 模型导出为 TFLite,并启用浮点16量化,推理更快、占用更低;
  5. 异步存储
    • 异步写入 SQLite 或切换到轻量级 NoSQL(如 TinyDB),降低阻塞;

四、压测数据(优化后)

指标 单页耗时 (秒) CPU 占用 内存占用
网络请求 + 代理复用 0.8 8% 55 MB
DOM 解析 0.6 12% 110 MB
批量模型推理 (TFLite) 0.4 20% 120 MB
多线程与异步存储 0.2 10% 25 MB
总计 2.0 50% 310 MB

五、改进结果

  • 平均单页耗时 从 5.0 秒降至 2.0 秒,性能提升 60%+;
  • 内存占用 减少 60 MB,推理内存占比降低;
  • CPU 利用率 更均衡,多线程并发可支撑更高并发量。
  • 整体爬虫更稳定,并可扩展至分布式部署。

代码示例

import time
import requests
from bs4 import BeautifulSoup
import sqlite3
import tensorflow as tf
import numpy as np
from concurrent.futures import ThreadPoolExecutor

# -----配置代理 IP(亿牛云爬虫代理示例 www.16yun.cn)-----
PROXY_HOST = "proxy.16yun.cn"
PROXY_PORT = 8100
PROXY_USER = "16YUN"
PROXY_PASS = "16IP"
proxy_meta = f"http://{PROXY_USER}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}"
proxies = {
   
    "http": proxy_meta,
    "https": proxy_meta,
}

# --------- HTTP 会话与头部设置 ---------
session = requests.Session()
session.proxies.update(proxies)
session.headers.update({
   
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
                  "(KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
})
# 示例 Cookie 设置
session.cookies.set("st_si", "123456789", domain="eastmoney.com")
session.cookies.set("st_asi", "abcdefg", domain="eastmoney.com")


# --------- 数据库初始化 ---------
conn = sqlite3.connect("eastmoney_news.db", check_same_thread=False)
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS news (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    title TEXT,
    pub_time TEXT,
    content TEXT
)
""")
conn.commit()


# --------- 加载并量化模型(TFLite) ---------
# 假设已有 Keras 模型 'content_block_model.h5',先转换为 TFLite
def convert_to_tflite(h5_path, tflite_path):
    model = tf.keras.models.load_model(h5_path)
    converter = tf.lite.TFLiteConverter.from_keras_model(model)
    converter.optimizations = [tf.lite.Optimize.DEFAULT]
    tflite_model = converter.convert()
    with open(tflite_path, "wb") as f:
        f.write(tflite_model)

# convert_to_tflite("content_block_model.h5", "model_quant.tflite")  # 一次性执行

# 加载 TFLite 模型
interpreter = tf.lite.Interpreter(model_path="model_quant.tflite")
interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()

# 模型预测函数(批量)
def predict_blocks(text_list):
    # 文本预处理示例:截断/填充到固定长度
    seqs = [[ord(c) for c in text[:200]] + [0] * (200 - len(text[:200])) for text in text_list]
    inp = np.array(seqs, dtype=np.float32)
    interpreter.set_tensor(input_details[0]['index'], inp)
    interpreter.invoke()
    preds = interpreter.get_tensor(output_details[0]['index'])
    # 返回布尔列表,True 表示为“关键区块”
    return [bool(p[1] > 0.5) for p in preds]


# --------- 爬取解析函数 ---------
def fetch_and_parse(url):
    start = time.time()

    # 1. 获取页面
    resp = session.get(url, timeout=10)
    resp.raise_for_status()
    # 2. 解析 DOM
    soup = BeautifulSoup(resp.text, "lxml")
    # 3. 提取候选区块(示例:所有 <div>)
    divs = soup.find_all("div")
    texts = [div.get_text(strip=True) for div in divs]
    # 4. 批量模型预测
    is_key = predict_blocks(texts)
    # 5. 筛选关键区块并抽取新闻字段
    news_items = []
    for div, flag in zip(divs, is_key):
        if not flag:
            continue
        title_tag = div.find("h1") or div.find("h2") or div.find("h3")
        time_tag = div.find("span", class_="time") or div.find("em")
        content = div.get_text(strip=True)
        if title_tag and time_tag:
            news_items.append({
   
                "title": title_tag.get_text(strip=True),
                "pub_time": time_tag.get_text(strip=True),
                "content": content
            })
    # 6. 存储到 SQLite
    for item in news_items:
        cursor.execute(
            "INSERT INTO news (title, pub_time, content) VALUES (?, ?, ?)",
            (item["title"], item["pub_time"], item["content"])
        )
    conn.commit()

    end = time.time()
    return end - start  # 返回耗时


# --------- 多线程压测 ---------
if __name__ == "__main__":
    urls = [
        "https://www.eastmoney.com/a/20250422XYZ.html",
        # ... 更多新闻页 URL 列表 ...
    ]
    with ThreadPoolExecutor(max_workers=5) as executor:
        times = list(executor.map(fetch_and_parse, urls))
    print(f"平均单页耗时:{sum(times)/len(times):.2f} 秒")

说明

  • 上述代码中,爬虫代理、Cookie、User-Agent 都已配置;
  • 将 Keras 模型量化为 TFLite 并启用批量推理,缩短深度学习部分耗时;
  • 使用 ThreadPoolExecutor 并发抓取与解析;
  • 最终压测中,多线程 + 模型量化后,平均单页耗时降至约 2 秒。

通过以上性能调优思路和代码实现,可显著提高基于深度学习的 DOM 内容区块识别爬虫的效率,为大规模抓取与分类存储奠定坚实基础。

相关文章
|
1月前
|
机器学习/深度学习 编解码 人工智能
计算机视觉五大技术——深度学习在图像处理中的应用
深度学习利用多层神经网络实现人工智能,计算机视觉是其重要应用之一。图像分类通过卷积神经网络(CNN)判断图片类别,如“猫”或“狗”。目标检测不仅识别物体,还确定其位置,R-CNN系列模型逐步优化检测速度与精度。语义分割对图像每个像素分类,FCN开创像素级分类范式,DeepLab等进一步提升细节表现。实例分割结合目标检测与语义分割,Mask R-CNN实现精准实例区分。关键点检测用于人体姿态估计、人脸特征识别等,OpenPose和HRNet等技术推动该领域发展。这些方法在效率与准确性上不断进步,广泛应用于实际场景。
346 64
计算机视觉五大技术——深度学习在图像处理中的应用
|
4月前
|
机器学习/深度学习 运维 安全
深度学习在安全事件检测中的应用:守护数字世界的利器
深度学习在安全事件检测中的应用:守护数字世界的利器
197 22
|
3月前
|
机器学习/深度学习 人工智能 运维
深度学习在流量监控中的革命性应用
深度学习在流量监控中的革命性应用
123 40
|
2月前
|
JavaScript 前端开发 API
JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等,array.map()的使用详解(附实际应用代码)
array.map()可以用来数据转换、创建派生数组、应用函数、链式调用、异步数据流处理、复杂API请求梳理、提供DOM操作、用来搜索和过滤等,比for好用太多了,主要是写法简单,并且非常直观,并且能提升代码的可读性,也就提升了Long Term代码的可维护性。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
3月前
|
机器学习/深度学习 运维 资源调度
深度学习在资源利用率优化中的应用:让服务器更聪明
深度学习在资源利用率优化中的应用:让服务器更聪明
185 6
|
4月前
|
机器学习/深度学习 传感器 人工智能
穹彻智能-上交大最新Nature子刊速递:解析深度学习驱动的视触觉动态重建方案
上海交大研究团队在Nature子刊发表论文,提出基于深度学习的视触觉动态重建方案,结合高密度可拉伸触觉手套与视觉-触觉联合学习框架,实现手部与物体间力量型交互的实时捕捉和重建。该方案包含1152个触觉感知单元,通过应变干扰抑制方法提高测量准确性,平均重建误差仅1.8厘米。实验结果显示,其在物体重建的准确性和鲁棒性方面优于现有方法,为虚拟现实、远程医疗等领域带来新突破。
123 32
|
3月前
|
机器学习/深度学习 自然语言处理 监控
深入探索:深度学习在时间序列预测中的强大应用与实现
时间序列分析是数据科学和机器学习中一个重要的研究领域,广泛应用于金融市场、天气预报、能源管理、交通预测、健康监控等多个领域。时间序列数据具有顺序相关性,通常展示出时间上较强的依赖性,因此简单的传统回归模型往往不能捕捉其中复杂的动态特征。深度学习通过其非线性建模能力和层次结构的特征提取能力,能够有效地捕捉复杂的时间相关性和非线性动态变化模式,从而在时间序列分析中展现出极大的潜力。
|
7月前
|
JavaScript
DOM 节点列表长度(Node List Length)
DOM 节点列表长度(Node List Length)
|
7月前
|
JavaScript
HTML DOM 节点树
HTML DOM 节点是指在 HTML 文档对象模型中,文档中的所有内容都被视为节点。整个文档是一个文档节点,每个 HTML 元素是元素节点,元素内的文本是文本节点,属性是属性节点,注释是注释节点。DOM 将文档表示为节点树,节点之间有父子和同胞关系。
|
7月前
|
JavaScript
HTML DOM 节点
HTML DOM(文档对象模型)将HTML文档视为节点树,其中每个部分都是节点:文档本身是文档节点,HTML元素是元素节点,元素内的文本是文本节点,属性是属性节点,注释是注释节点。节点间存在父子及同胞关系,形成层次结构。