拒绝想当然,不看文档导致GNE 的隐秘 bug

简介: 拒绝想当然,不看文档导致GNE 的隐秘 bug

摄影:产品经理在杭州竟然还能吃到豌豆尖,kingname 激动得喝了一碗汤

GNE[1]上线 4 天,已经有很多朋友通过它来编写自己的新闻类网页通用爬虫。

今天有一个用户来跟我反馈,GNE 0.1.4 版本在提取澎湃新闻时,只能提取一小部分的内容。

一开始我以为是提取算法有问题,Debug 了半天,最后才发现,是新闻正文在预处理的时候,就被提前删除了!

为了解释这个问题,我们用一小段 HTML 代码来还原当时的场景:

h = '''
<html>
    <body>
        <div class="txt">
        第一行
        <p class="con" />
        第二行
        <p class="con" />
        第三行
        </div>
    </body>
</html>
'''

阅读过 GNE 源代码的朋友都知道,GNE 会在预处理阶段尽可能移除没什么用的 HTML 标签。例如上面这段代码中的两行<p class="con" />都属于会干扰提取结果,且对提取没有任何帮助的标签。

于是我们使用 lxml 库的方法来移除它:

from lxml.html import fromstring
selector = fromstring(h)
useless_list = selector.xpath('//p[@class="con"]')
for useless in useless_list:
    useless.getparent().remove(useless)

根据想当然的理论:

  1. 找到<p class="con" />标签
  2. 找到它的父标签
  3. 从父标签里面把这两个无效标签移除掉

整个过程看起来没有问题,并且预期移除以后的 HTML 应该是这样的:

h = '''
<html>
    <body>
        <div class="txt">
        第一行
        第二行
        第三行
        </div>
    </body>
</html>
'''

但实际上,现实情况与想当然的情况自然不一样。真正的输出结果如下图所示:

<div class="txt">这个标签下面的text()有三行,分别为第一行第二行第三行。但是使用上面的代码移除时,第二行第三行都一并被删除了。

这是因为,这就是ElementTree.remove这个方法的行为。它不仅会移除这个节点,还会移除这个节点父节点的 text()中,位于这个节点后面的所有内容。

所以,正常的做法应该是直接调用要被移除这个节点的.drop_tag()方法。我们修改一下上面的代码:

from lxml.html import fromstring
from html import unescape
from lxml.html import etree
h = '''
<html>
    <body>
        <div class="txt">
        第一行
        <p class="con" />
        第二行
        <p class="con" />
        第三行
        </div>
    </body>
</html>
'''
selector = fromstring(h)
useless_list = selector.xpath('//p[@class="con"]')
for useless in useless_list:
    useless.drop_tag()
print(unescape(etree.tostring(selector).decode()))

运行效果如下图所示。

成功达到了我们想要的目的。

GNE 已经更新了版本,修复了这个 bug。使用 GNE 的同学请升级到 0.1.5 以上版本:

pip install --upgrade gne
目录
相关文章
|
Oracle Java 关系型数据库
mybatis批量删除Batch delete
mybatis批量删除Batch delete
mybatis批量删除Batch delete
|
网络协议 Linux 开发工具
Linux|麒麟操作系统实现多路RTMP|RTSP播放
无论是Windows平台还是Linux,多路播放诉求非常普遍,比如针对智慧工地、展馆、教育等宏观场景下的摄像头展示,关于RTSP或RTMP直播播放器开发需要注意的点,可参考之前博客,总的来说有以下一些点:
382 0
|
6月前
|
开发框架 人工智能 Java
破茧成蝶:传统J2EE应用无缝升级AI原生
本文探讨了技术挑战和解决方案,还提供了具体的实施步骤,旨在帮助企业顺利实现从传统应用到智能应用的过渡。
破茧成蝶:传统J2EE应用无缝升级AI原生
|
2月前
|
人工智能 算法 安全
算法备案新手攻略——2025全网最新最详细解读版
本文介绍了算法备案的背景、法规依据、备案类型及流程,涵盖生成合成、个性化推送等五大算法类型,并详细说明所需材料与备案周期,强调未备案将面临行政处罚甚至刑事追责,助力企业合规运营。
|
8月前
|
机器学习/深度学习 人工智能 算法
生物医药领域-分子对接SOTA模型洞察
该文介绍了分子对接的作用过程、应用场景及分类,总结了现有软件的核心内容与评估指标,并分析了KarmaDock、DiffBindFR和RosettaVS三种最新模型的细节、性能和应用领域。研究指出,未来应关注模型长板特征,开发超大规模虚拟筛选平台以提升药物发现效率。
|
11月前
|
Kubernetes API Docker
构建高效后端服务:微服务架构的深度实践与优化####
本文深入探讨了微服务架构在现代后端开发中的应用,通过剖析其核心概念、设计原则及实施策略,结合具体案例分析,展示了如何有效提升系统的可扩展性、可靠性和维护性。文章还详细阐述了微服务拆分的方法论、服务间通信的最佳实践、以及容器化与编排工具(如Docker和Kubernetes)的应用技巧,为读者提供了一份全面的微服务架构落地指南。 ####
|
11月前
|
SQL 监控 大数据
优化AnalyticDB性能:查询优化与资源管理
【10月更文挑战第25天】在大数据时代,实时分析和处理海量数据的能力成为了企业竞争力的重要组成部分。阿里云的AnalyticDB(ADB)是一款完全托管的实时数据仓库服务,支持PB级数据的秒级查询响应。作为一名已经有一定AnalyticDB使用经验的开发者,我发现通过合理的查询优化和资源管理可以显著提升ADB的性能。本文将从个人角度出发,分享我在实践中积累的经验,帮助读者更好地利用ADB的强大功能。
295 0
|
安全 NoSQL Java
JeecgBoot应用Spring Authorization Server
Spring Authorizaiton Server, 简称 sas,是一个授权服务器框架,提供 OAuth2.1 与 Open Connect 1.0 认证规范及其他规范的实现,它建立在 Spring Security 之上,为构建 OpenID Connect 1.0 Identity Provider 和 OAuth2 授权服务器产品提供了一个安全、轻量级和可定制的基础
225 2
|
数据安全/隐私保护
最新2024阿里云国际站最便捷注册流程
阿里云国际分销商TG@cloudicc
1096 0
最新2024阿里云国际站最便捷注册流程