我正在使用BeautifulSoup解析几个XML文档源,并希望进行一些预处理以使用自定义XML标记替换非标准CDATA
标记。举例说明:
以下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查询)。我还尝试了一些使用.findAll('cdata', text=True)
的不同方法,并将BeautifulSoup replaceWith()
方法应用于每个结果NavigableString
。我所做的尝试导致了没有替换,或者看起来像是一个递归循环。
我很高兴发布我之前的尝试,但鉴于此处的问题非常简单,我希望有人可以发布一个明确的示例,说明如何使用BeautifulSoup 3完成上述搜索和替换。
答案 0 :(得分:2)
CData
是NavigableString
的子类,因此您可以找到所有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
对象内容的唯一方法是切片
它,就像上面的代码片段一样。 str(navstr)
会保留所有内容
<![CDATA[...]]>
垃圾,这显然是你不想要的。在BS4中,str(navstr)
给你没有垃圾的内容。