GNE 预处理技术——如何移除特定标签但是保留文字到父标签

简介: GNE 预处理技术——如何移除特定标签但是保留文字到父标签

摄影:产品经理

厨师:kingname


在开发新闻网页正文通用抽取器 GNE的过程中,需要对目标网页的源代码进行一些预处理,从而提高正文抓取的准确性。其中之一就是把 <p>标签内部的 <span>标签中的文本,合并到 <p>标签中,再删除 <span> 标签。

例如:

<html>
    <head>
        <title>演示合并节点</title>
    </head>
    <body>
        <div>
            <p>你好,<span>世界;</span>你好,<span>产品经理</span></p>
        </div>
    </body>
</html>

需要转换为:

<html>
    <head>
        <title>演示合并节点</title>
    </head>
    <body>
        <div>
            <p>你好,世界;你好,产品经理</p>
        </div>
    </body>
</html>

在原来做定向爬虫的时候,这本不是什么问题,因为使用 XPath 可以直接提取所有内容:

  1. 运行效果如下图所示:
1. from lxml.html import fromstring
2. selector = fromstring(html)
3. text = ''.join(selector.xpath('//p//text()'))
4. print(text)

但在通用新闻抽取器里面不能这样写。因为并不是所有的 <p>标签中的内容都是新闻正文。GNE 有一套算法来计算并寻找全部包含真正有效内容的 <p>标签。这就要求在预处理阶段,需要把 <p>标签里面的 <span>标签合并到 <p>标签里面。

可能有人的第一反应是:先把 <p> 标签里面的内容提取出来,然后再把 <span> 标签里面的内容提取出来,并添加到 <p> 标签中。这不就解决问题了吗?

但实际上并没有这么简单。以上面的 HTML 代码为了,如果按照这种简单的解法,那么分别提取以后会得到如下内容:

现在问题来了,你怎么知道 <span> 标签中提取出来的这两个字符串 世界, 产品经理,分别应该插入到 <p> 标签结果列表中的哪个位置?所以这种方案并不可取。

那么又有人问,能不能使用 XPath 的 string关键字把 <p> 标签下面的所有文本直接提取出来,再作处理呢?这样不就可以忽略标签差异了吗?在上面的 html 代码中,这种方案是可行的:

但是,这种方案不能应用到 GNE 中。这是由于这种做法,会无差别移除所有的标签。但是 <p> 标签下面的 <a>标签是有用的,它在用于过滤导航栏或者推荐新闻这种类型的干扰内容中会起到很大的作用。所以 <a>标签必需保留。

那么,本文标题提到的问题:

如何移除指定标签,但是保留它的文本,合并到父标签中?


应该如何解决呢?

实际上,这个问题在 lxml 中有现成的办法解决,他就是 etree.strip_tags

使用方法如下:

from lxml.html import etree
etree.strip_tags(element, '标签1', '标签2', '标签3')

在本文的例子中,解决方案如下:

from lxml.html import fromstring, etree
selector = fromstring(html)
p_tag_list = selector.xpath('//p')
for p_tag in p_tag_list:
    etree.strip_tags(p_tag, 'span')
text = ''.join(selector.xpath('//p/text()'))
print(text)

运行效果如下图所示:

需要注意的是, etree.strip_tags()会直接修改原始Dom 树,不需要返回修改结果。

目录
相关文章
|
机器学习/深度学习 算法 数据可视化
浅析特征数据离散化的几种方法(上)
什么是离散化? 离散化就是把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。通俗的说,离散化是在不改变数据相对大小的条件下,对数据进行相应的缩小。例如:
|
自然语言处理 BI 数据处理
【数据对比】综合分析百度情感分析以及华为情感分析的差异,我有了如下结果
【数据对比】综合分析百度情感分析以及华为情感分析的差异,我有了如下结果
555 0
|
7月前
|
IDE 开发工具 C++
JetBrains CLion 2025.1 发布 - C 和 C++ 跨平台 IDE
JetBrains CLion 2025.1 (macOS, Linux, Windows) - C 和 C++ 跨平台 IDE
322 0
|
SQL 算法 Java
Myqsql使用Sharding-JDBC分表分库和读写分离 2
Myqsql使用Sharding-JDBC分表分库和读写分离
447 0
|
存储 移动开发 监控
微信支付开发避坑指南
【9月更文挑战第11天】在进行微信支付开发时,需遵循官方文档,确保权限和参数配置正确。开发中应注重安全,验证用户输入,合理安排接口调用顺序,并处理异常。上线后需实时监控支付状态,定期检查配置,关注安全更新,确保系统稳定运行。
288 3
|
人工智能 物联网 5G
移动应用与系统:开发、优化与未来趋势
【10月更文挑战第25天】 本文深入探讨了移动应用开发和移动操作系统的关键技术、挑战及未来发展趋势。通过分析当前市场主流的移动操作系统,如Android和iOS,以及它们在用户体验、安全性和性能方面的差异,本文旨在为开发者提供宝贵的见解和建议。同时,文章还讨论了移动应用开发中的最佳实践,包括跨平台开发工具的选择、性能优化技巧以及如何应对不断变化的技术环境。最后,本文展望了移动应用与系统的未来,包括人工智能、物联网和5G技术的融合,以及这些技术如何推动移动应用向更智能、更互联的方向发展。
327 60
|
11月前
|
移动开发 小程序 前端开发
使用php开发圈子系统特点,如何获取圈子系统源码,社交圈子运营以及圈子系统的功能特点,圈子系统,允许二开,免费源码,APP 小程序 H5
开发一个圈子系统(也称为社交网络或社群系统)可以是一个复杂但非常有趣的项目。以下是一些关键特点和步骤,帮助你理解如何开发、获取源码以及运营一个圈子系统。
445 4
|
前端开发 JavaScript 数据库
https页面加载http资源的解决方法
https页面加载http资源的解决方法
337 4
|
12月前
|
监控 Java Shell
监控堆外第三方监控工具Zabbix
监控堆外第三方监控工具Zabbix
294 5
|
缓存 监控 NoSQL
【MongoDB 专栏】MongoDB 的内存管理与优化
【5月更文挑战第11天】MongoDB的内存管理优化对性能至关重要,涉及数据缓存、索引及执行操作的内存使用。动态内存管理根据访问模式和负载调整,可通过配置参数优化,如设置合适缓存大小,调整内存分配参数。索引管理也很重要,需定期评估优化,避免内存占用过高。监控内存使用、数据清理压缩、架构规划也是优化手段。面对挑战,如高并发下的内存不足,需灵活调整策略,平衡系统资源。不断学习新方法,提升内存管理能力,以优化MongoDB性能。
758 2
【MongoDB 专栏】MongoDB 的内存管理与优化