【问题标题】:Parsing an unnamed element in beautifulsoup解析 Beautifulsoup 中的未命名元素
【发布时间】:2015-04-10 14:03:45
【问题描述】:

对于某个类名的跨度,我需要解析未命名的 br 元素之间的某些文本。在本例中,我需要 0.36,在本例中,它位于命名属性“DS”之后。

这是我尝试过的。

from bs4 import BeautifulSoup  
html="""
<pre5 style="">                                                    
    <br><br>
    <span class="field-name">DS :</span>                               
    0.36 [null]<br><br> <br> <span> <b>FC</b> </span><span> : 0.0 </span><br>  <br> <span> <b>FDC</b> </span><span> : 0.36 </span><br>  <br> <span> <b>LDD</b> </span><span> : 4838400000 </span><br>  <br> <span> <b>IFS</b> </span><span> : 0.5333333 </span><br> 
  </pre5>
"""
soup = BeautifulSoup(html,'lxml')
divTag = soup.find_all("pre5", {"style":""})

for tag in divTag:
    tdTags = tag.find_all("span", {"class":"field-name"})
    for tag in tdTags:
        print tag.text 
        # print DS :, but I want 0.36


#Alternatively,
soup = BeautifulSoup(html,'lxml')
print str(soup.span.next_sibling.strip()).replace('[null]','')
#prints 0.36 , but I would like to print by making sure that this element actually comes along with DS: and not just by the "immediate next sibilng" - is there a way to respect the named attribute DS and fetch the value for it ? 

也是通过字符串解析/拆分/替换,会比较慢,可以直接用树形结构吗?

编辑,在这种情况下,DS 的值应为 0.007。不能保证 DS 将是 span 类中的第一个元素。

html="""
<pre5 style="">                                                    
    <br><br>
    <span class="field-name">FC :</span>                               
    0.36 [null]<br><br> <br> <span> <b>DS:</b> </span><span> : 0.007 </span><br>  <br> <span> <b>FDC</b> </span><span> : 0.36 </span><br>  <br> <span> <b>LDD</b> </span><span> : 4838400000 </span><br>  <br> <span> <b>IFS</b> </span><span> : 0.5333333 </span><br> 
  </pre5>
"""

【问题讨论】:

    标签: python-2.7 parsing beautifulsoup lxml


    【解决方案1】:

    由于文本DS可以在&lt;span&gt;&lt;b&gt;标签内,数据也可以在&lt;span&gt;标签内,您可以像这样搜索标签:

    html = """
    <pre5 style="">
        <br><br>
        <span class="field-name">DS :</span>
        0.36 [null]<br><br> <br> <span> <b>FC</b> </span><span> : 0.0 </span><br>  <br> <span> <b>FDC</b> </span><span> : 0.36 </span><br>  <br> <span> <b>LDD</b> </span><span> : 4838400000 </span><br>  <br> <span> <b>IFS</b> </span><span> : 0.5333333 </span><br>
      </pre5>
    <pre5 style="">
        <br><br>
        <span class="field-name">FC :</span>
        0.36 [null]<br><br> <br> <span> <b>DS:</b> </span><span> : 0.007 </span><br>  <br> <span> <b>FDC</b> </span><span> : 0.36 </span><br>  <br> <span> <b>LDD</b> </span><span> : 4838400000 </span><br>  <br> <span> <b>IFS</b> </span><span> : 0.5333333 </span><br>
      </pre5>
    """
    
    soup = BeautifulSoup(html, 'lxml')
    divTag = soup.find_all("pre5", {"style": ""})
    
    import re
    
    for tag in divTag:
        tdTags = tag.find_all(["span", "b"], text=re.compile(r'DS\s*:'))
        for tag in tdTags:
            if tag.nextSibling.strip():
                print tag.nextSibling.replace('[null]', '').strip()
            else:
                print tag.findNext("span").text.replace(':', '').strip()
    

    这会给你输出:

    0.36
    0.007
    

    【讨论】:

      【解决方案2】:

      如果我理解正确,您说要提取的文本就在&lt;span&gt; 标记之后,因此您可以使用next_element 两次。第一个用于标记内的文本,第二个用于标记后面的文本。它似乎在这里工作,像这样:

      from bs4 import BeautifulSoup  
      html="""
      <pre5 style="">                                                    
          <br><br>
          <span class="field-name">DS :</span>                               
          0.36 [null]<br><br> <br> <span> <b>FC</b> </span><span> : 0.0 </span><br>  <br> <span> <b>FDC</b> </span><span> : 0.36 </span><br>  <br> <span> <b>LDD</b> </span><span> : 4838400000 </span><br>  <br> <span> <b>IFS</b> </span><span> : 0.5333333 </span><br> 
        </pre5>
      """
      soup = BeautifulSoup(html,'lxml')
      divTag = soup.find_all("pre5", {"style":""})
      
      for tag in divTag:
          tdTags = tag.find_all("span", {"class":"field-name"})
          for tag in tdTags:
              print tag.next_element.next_element.replace('[null]', '')
      

      它产生(之后可以删除一些空白):

      0.36
      

      【讨论】:

      • 您的代码仍然假定 span class="field-name">DS : 将首先出现。你能编辑这个以确保如果 DS: 是 span 类中的第二个,我们仍然会得到 "DS" 的正确浮点数
      • @ekta:你的解释我没有得到新的xml 数据。您能否编辑您的问题并添加它以检查我的解决方案不适合的方式?
      • @Birel 请参见上面的编辑
      • @ekta: 看来salman wahed 明白了,所以先看看他的解决方案。
      猜你喜欢
      • 1970-01-01
      • 2020-06-22
      • 2016-10-25
      • 1970-01-01
      • 2015-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多