只从这个元素中提取文本,而不是它的子元素

Posted

技术标签:

【中文标题】只从这个元素中提取文本,而不是它的子元素【英文标题】:Only extracting text from this element, not its children 【发布时间】:2011-06-27 01:51:39 【问题描述】:

我只想从我的汤的最顶部元素中提取文本;然而,soup.text 也给出了所有子元素的文本:

我有

import BeautifulSoup
soup=BeautifulSoup.BeautifulSoup('<html>yes<b>no</b></html>')
print soup.text

这个的输出是yesno。我只想说“是”。

实现这一目标的最佳方法是什么?

编辑:我还希望在解析“&lt;html&gt;&lt;b&gt;no&lt;/b&gt;yes&lt;/html&gt;”时输出yes

【问题讨论】:

BeautifulSOAP 已被移除。要仅在 bs4 中获取当前元素的文本,请参阅 @Horst Miller 的回答 here 没有 BeautifulSOAP 的最佳答案仍然有效。 .find(text=True, recursive=False) 感觉比 contents 列表组合和类型检查更干净。 【参考方案1】:

你可以使用contents

>>> print soup.html.contents[0]
yes

或者要获取html下的所有文本,使用findAll(text=True, recursive=False)

>>> soup = BeautifulSoup.BeautifulSOAP('<html>x<b>no</b>yes</html>')
>>> soup.html.findAll(text=True, recursive=False) 
[u'x', u'yes']

以上连接形成单个字符串

>>> ''.join(soup.html.findAll(text=True, recursive=False)) 
u'xyes'

【讨论】:

有点工作,但遗憾的是,当 html 被反转时没有帮助:&lt;html&gt;&lt;b&gt;no&lt;/b&gt;yes&lt;/html&gt;。我想我可以遍历内容试图找到不是标签的部分。 findAll(text=True, recursive=False) 那是我的果酱宝贝,尤其是recursive=False 位!【参考方案2】:

.find(text=True) 呢?

>>> BeautifulSoup.BeautifulSOAP('<html>yes<b>no</b></html>').find(text=True)
u'yes'
>>> BeautifulSoup.BeautifulSOAP('<html><b>no</b>yes</html>').find(text=True)
u'no'

编辑:

我想我现在已经明白你想要什么了。试试这个:

>>> BeautifulSoup.BeautifulSOAP('<html><b>no</b>yes</html>').html.find(text=True, recursive=False)
u'yes'
>>> BeautifulSoup.BeautifulSOAP('<html>yes<b>no</b></html>').html.find(text=True, recursive=False)
u'yes'

【讨论】:

在第二种情况下(no,仍然在b标签中)我仍然希望输出为yes @jbochi 不适用于此&lt;h2&gt;&lt;a aria-expanded="false" aria-owns="faqGen5" href="#"&gt;Is &lt;span class="nobreak"&gt;XFINITY WiFi&lt;/span&gt; secure?&lt;/a&gt;&lt;/h2&gt;。我需要为find(text=True) 获取Is secure?【参考方案3】:

您可能想查看 lxml 的 soupparser 模块,它支持 XPath:

>>> from lxml.html.soupparser import fromstring
>>> s1 = '<html>yes<b>no</b></html>'
>>> s2 = '<html><b>no</b>yes</html>'
>>> soup1 = fromstring(s1)
>>> soup2 = fromstring(s2)
>>> soup1.xpath("text()")
['yes']
>>> soup2.xpath("text()")
['yes']

【讨论】:

【参考方案4】:

这在 bs4 中适用于我:

import bs4
node = bs4.BeautifulSoup('<html><div>A<span>B</span>C</div></html>').find('div')
print "".join([t for t in node.contents if type(t)==bs4.element.NavigableString])

输出:

AC

【讨论】:

更多地是pythonisinstance(t, bs4.element.NavigableString) 不错!请注意,您的解决方案比“find_all(text=True, recursive=False)”更通用,因为它还会捕获标签“hiJso long”周围的文本得到'hilong'。取而代之的是 find_all 只得到第一个:'hi'

以上是关于只从这个元素中提取文本,而不是它的子元素的主要内容,如果未能解决你的问题,请参考以下文章

在我的插槽中包装动态添加的子元素

在XSD中,当可选的父元素出现时,它的子元素是必需的吗?

reactjs中如何将可选元素作为prop传递给组件

js为啥根据id就可以找到容器里的子元素,而根据类名就找不到?

DOM克隆操作(深克隆/浅克隆)

序列化 xml 文件的一部分。想要根上的命名空间,而不是序列化的子元素