【问题标题】:Using beautifulsoup to extract text between line breaks (e.g. <br /> tags)使用 beautifulsoup 提取换行符之间的文本(例如 <br /> 标签)
【发布时间】: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; 元素,但找不到在两者之间获取文本的方法。任何帮助将不胜感激。谢谢。

【问题讨论】:

    标签: python html html-parsing beautifulsoup


    【解决方案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 />
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-27
      • 2015-03-05
      • 1970-01-01
      • 2016-03-28
      相关资源
      最近更新 更多