【问题标题】:Replacing CDATA NavigableStrings with Tags in BeautifulSoup用 BeautifulSoup 中的标签替换 CDATA NavigableStrings
【发布时间】:2023-03-28 04:02:01
【问题描述】:

我正在使用 BeautifulSoup 解析几个 XML 文档提要,并希望进行一些预处理以将非标准的 CDATA 标记替换为自定义 XML 标记。举例说明:

以下 XML 源代码...

<title>The end of the world as we know it</title>
<category><![CDATA[Planking Dancing]]></category>
<pubDate><![CDATA[Sun, 16 Sep 2012 12:00:00 EDT]]></pubDate>
<dc:creator><![CDATA[Bart Simpson]]></dc:creator>

...会变成:

<title>The end of the world as we know it</title>
<category><myTag>Planking Dancing<myTag></category>
<pubDate><myTag>Sun, 16 Sep 2012 12:00:00 EDT<myTag></pubDate>
<dc:creator><myTag>Bart Simpson<myTag></dc:creator>

我认为以前没有在 SO 上问过这个问题(我尝试了几个不同的 SO 查询)。我还尝试了几种不同的方法,使用 .findAll('cdata', text=True) 并将 BeautifulSoup replaceWith() 方法应用于每个结果 NavigableString。我所做的尝试要么没有替换,要么看起来像一个递归循环。

我很高兴发布我之前的尝试,但鉴于这里的问题非常简单,我希望有人可以发布一个清晰的示例,说明如何使用 BeautifulSoup 3 完成上述搜索和替换。

【问题讨论】:

    标签: python xml xml-parsing beautifulsoup cdata


    【解决方案1】:

    CDataNavigableString 的子类,所以你可以找到所有CData 元素通过首先搜索所有NavigableString 对象,然后测试 是否每个都是CData 的实例。有了之后就很容易了 按照您的建议,使用replaceWith 替换:

    >>> from BeautifulSoup import BeautifulSoup, CData, Tag
    >>> source = """
    ... <title>The end of the world as we know it</title>
    ... <category><![CDATA[Planking Dancing]]></category>
    ... <pubDate><![CDATA[Sun, 16 Sep 2012 12:00:00 EDT]]></pubDate>
    ... <dc:creator><![CDATA[Bart Simpson]]></dc:creator>
    ... """
    >>> soup = BeautifulSoup(source)
    >>> for navstr in soup(text=True):
    ...     if isinstance(navstr, CData):
    ...         tag = Tag(soup, "myTag")
    ...         tag.insert(0, navstr[:])
    ...         navstr.replaceWith(tag)
    ... 
    >>> soup
    
    <title>The end of the world as we know it</title>
    <category><myTag>Planking Dancing</myTag></category>
    <pubdate><myTag>Sun, 16 Sep 2012 12:00:00 EDT</myTag></pubdate>
    <dc:creator><myTag>Bart Simpson</myTag></dc:creator>
    
    >>>
    

    几点说明:

    • 您可以像调用函数一样调用BeautifulSoup 对象,并且 效果和调用它的.findAll()方法一样。

    • 我知道在 BS3 中获取 CData 对象内容的唯一方法是切片 它,如上面的sn-p。 str(navstr) 将保留所有 &lt;![CDATA[...]]&gt; 垃圾,显然你不想要。在 BS4 中,str(navstr) 为您提供没有垃圾的内容。

    【讨论】:

      猜你喜欢
      • 2013-07-03
      • 1970-01-01
      • 1970-01-01
      • 2021-10-10
      • 2015-06-24
      • 1970-01-01
      • 2014-03-09
      • 2021-08-01
      • 2017-03-31
      相关资源
      最近更新 更多