使用 beautifulsoup 提取换行符之间的文本(例如 <br /> 标签)

Posted

技术标签:

【中文标题】使用 beautifulsoup 提取换行符之间的文本(例如 <br /> 标签)【英文标题】:Using beautifulsoup to extract text between line breaks (e.g. <br /> tags) 【发布时间】:2011-07-13 14:52:19 【问题描述】:

我在一个较大的文档中有以下 html

<br />
Important Text 1
<br />
<br />
Not Important Text
<br />
Important Text 2
<br />
Important Text 3
<br />
<br />
Non Important Text
<br />
Important Text 4
<br />

我目前正在使用 BeautifulSoup 来获取 HTML 中的其他元素,但我无法找到一种方法来获取 &lt;br /&gt; 标记之间的重要文本行。我可以隔离并导航到每个 &lt;br /&gt; 元素,但找不到在两者之间获取文本的方法。任何帮助将不胜感激。谢谢。

【问题讨论】:

【参考方案1】:

对 Ken Kinder 的回答略有改进。您可以改为访问 BeautifulSoup 元素的 stripped_strings 属性。例如,假设您的特定 HTML 块位于 span 标签内:


x = """<span><br />
Important Text 1
<br />
<br />
Not Important Text
<br />
Important Text 2
<br />
Important Text 3
<br />
<br />
Non Important Text
<br />
Important Text 4
<br /></span>"""

首先我们用 BeautifulSoup 解析x。然后查找元素,在本例中为span,然后访问stripped_strings 属性。像这样,

from bs4 import BeautifulSoup
soup = BeautifulSoup(x)
span = soup.find("span")
text = list(span.stripped_strings)

现在print(text) 将给出以下输出:

['Important Text 1',
 'Not Important Text',
 'Important Text 2',
 'Important Text 3',
 'Non Important Text',
 'Important Text 4']

【讨论】:

我得到 'list' 对象在此上不可调用 代码对我来说很好用。您在哪一行收到此错误? 这不会仅将文本沿 &lt;br&gt; 拆分,而是沿所有 HTML 标记。【参考方案2】:

如果您只想要两个 &lt;br /&gt; 标记之间的任何文本,您可以执行以下操作:

from BeautifulSoup import BeautifulSoup, NavigableString, Tag

input = '''<br />
Important Text 1
<br />
<br />
Not Important Text
<br />
Important Text 2
<br />
Important Text 3
<br />
<br />
Non Important Text
<br />
Important Text 4
<br />'''

soup = BeautifulSoup(input)

for br in soup.findAll('br'):
    next_s = br.nextSibling
    if not (next_s and isinstance(next_s,NavigableString)):
        continue
    next2_s = next_s.nextSibling
    if next2_s and isinstance(next2_s,Tag) and next2_s.name == 'br':
        text = str(next_s).strip()
        if text:
            print "Found:", next_s

但也许我误解了你的问题?您对问题的描述似乎与您的示例数据中的“重要”/“不重要”不匹配,所以我已经使用了描述;)

【讨论】:

啊,问题是我使用的是 findNextSibling(),这只是跳过文本并转到下一个换行符。使用 nextSibling 有效。感谢您的帮助! 很好的答案,这让我很头疼! next 不是 Python 中的保留字吗?也许不同的变量名会更好? (这是一个小问题,但这样的事情加起来!) duhaime:实际上它不是 Python 中的关键字(continue 在 Python 中相当于其他语言中的 next @André Christoffer Andersen:当然,是的,好点子!我已经在答案中改变了它,所以它不会影响内置函数。【参考方案3】:

以下内容对我有用:

for br in soup.findAll('br'):
    if str(type(br.contents[0])) == '<class \'BeautifulSoup.NavigableString\'>':
       print br.contents[0]

【讨论】:

请不要依赖对象的字符串表示来实现代码逻辑。【参考方案4】:

因此,出于测试目的,我们假设这段 HTML 位于 span 标记内:

x = """<span><br />
Important Text 1
<br />
<br />
Not Important Text
<br />
Important Text 2
<br />
Important Text 3
<br />
<br />
Non Important Text
<br />
Important Text 4
<br /></span>"""

现在我要解析它并找到我的 span 标签:

from BeautifulSoup import BeautifulSoup
y = soup.find('span')

如果您在y.childGenerator() 中迭代生成器,您将获得 br 和文本:

In [4]: for a in y.childGenerator(): print type(a), str(a)
   ....: 
<type 'instance'> <br />
<class 'BeautifulSoup.NavigableString'> 
Important Text 1

<type 'instance'> <br />
<class 'BeautifulSoup.NavigableString'> 

<type 'instance'> <br />
<class 'BeautifulSoup.NavigableString'> 
Not Important Text

<type 'instance'> <br />
<class 'BeautifulSoup.NavigableString'> 
Important Text 2

<type 'instance'> <br />
<class 'BeautifulSoup.NavigableString'> 
Important Text 3

<type 'instance'> <br />
<class 'BeautifulSoup.NavigableString'> 

<type 'instance'> <br />
<class 'BeautifulSoup.NavigableString'> 
Non Important Text

<type 'instance'> <br />
<class 'BeautifulSoup.NavigableString'> 
Important Text 4

<type 'instance'> <br />

【讨论】:

以上是关于使用 beautifulsoup 提取换行符之间的文本(例如 <br /> 标签)的主要内容,如果未能解决你的问题,请参考以下文章

使用 BeautifulSoup 提取标签之间的文本

python,提取HTML中左右没有标签的内容,怎么提取?

Python BeautifulSoup 提取元素之间的文本

从 BeautifulSoup 4.6 中的两个 HTML 标签之间提取 HTML

使用 BeautifulSoup 迭代 XML 以提取特定标签并存储在变量中

Beautifulsoup - get_text,单行输出