【问题标题】:Merge multiple <br /> tags to a single one with python lxml使用python lxml将多个<br />标签合并为一个标签
【发布时间】:2013-12-26 04:18:12
【问题描述】:

我有一个用于清理抓取的 html 内容的 python 脚本,它使用 BeautifulSoup4 并且运行良好。最近我决定学习 lxml,但我发现这些教程(对我来说)更难遵循。例如,我使用以下代码将多个&lt;br /&gt; 标签合并为一个,即如果有多个&lt;br /&gt; 标签,则删除所有标签,只保留一个:

from bs4 import BeautifulSoup, Tag
data = 'foo<br /><br>bar. <p>foo<br/><br id="1"><br/>bar'
soup = BeautifulSoup(data)
for br in soup.find_all("br"):
    while isinstance(br.next_sibling, Tag) and br.next_sibling.name == 'br':
        br.next_sibling.extract()
print soup
<html><body><p>foo<br/>bar. </p><p>foo<br/>bar</p></body></html>

我如何在 lxml 中实现这一点?谢谢,

【问题讨论】:

  • 如果安装了lxml,那么BeautifulSoup会将其静默(可能有害)用作解析器。
  • 这让我很困惑:我听说lxml比bs4快,按照你的说法,只要我安装了lxml,即使我使用bs4我也不会失去速度?
  • 唯一重要的基准是您的代码。测量它:在未安装 lxml 的 virtualenv 中运行(import lxml 必须失败),然后在安装 lxml 的 virtualenv 中运行(您也可以显式指定解析器)。

标签: python lxml


【解决方案1】:

您可以尝试.drop_tag() 方法来删​​除重复连续出现的&lt;br/&gt; 标签:

from lxml import html

doc = html.fromstring(data)
for br in doc.findall('.//br'):
    if br.tail is None: # no text immediately after <br> tag
        for dup in br.itersiblings():
            if dup.tag != 'br': # don't merge if there is another tag inbetween
                break
            dup.drop_tag()
            if dup.tail is not None: # don't merge if there is a text inbetween
               break

print(html.tostring(doc))
# -> <div><p>foo<br>bar. </p><p>foo<br>bar</p></div>

【讨论】:

    猜你喜欢
    • 2023-01-18
    • 2015-08-30
    • 2010-09-13
    • 2018-03-10
    • 1970-01-01
    • 1970-01-01
    • 2015-08-15
    • 2015-05-21
    • 2013-02-15
    相关资源
    最近更新 更多