【问题标题】:Get text from div without any tags and special characters从没有任何标签和特殊字符的 div 获取文本
【发布时间】:2014-10-20 10:43:24
【问题描述】:

我有一个 html 文件,其中 div 标签中有许多不同的文本结构。我唯一想要的是在这些标签中获取文本,但没有标签、换行符等。

例如这个html div:

<div class="textNahlad">
     <i>Informácie pre záujemcu:</i>
     <br>
    Výberový pohovor je potrebné vopred dojednať telefonicky
     <br>
</div>

但也可以是:

<div class="textNahlad">
         <b>Informácie pre záujemcu:</b>
         <br>
         <br>
         <br>
        <i>Výberový pohovor je potrebné vopred dojednať telefonicky</i>
         <br>
</div>

所以结果是:Informácie pre záujemcu: Výberový pohovor je potrebné vopred dojednať telefonicky

我很好奇 Python/BS4 中是否有一个函数可以只返回没有标签和换行符和其他混乱的文本。

find.('div',class_="textNahlad") 不起作用

编辑:我尝试使用 .contents 来执行此操作,并且对于每个内容检查,无论是文本还是标记,如果标记,则获取文本,但它无法正常工作。

【问题讨论】:

    标签: python html beautifulsoup


    【解决方案1】:

    您可以按如下方式访问stripped_strings 属性:

    from bs4 import BeautifulSoup
    
    html1 = '''<div class="textNahlad">
         <i>Informácie pre záujemcu:</i>
         <br>
        Výberový pohovor je potrebné vopred dojednať telefonicky
         <br>
    </div>'''
    
    soup1 = BeautifulSoup(html1)
    
    html2 = '''<div class="textNahlad">
             <b>Informácie pre záujemcu:</b>
             <br>
             <br>
             <br>
            <i>Výberový pohovor je potrebné vopred dojednať telefonicky</i>
             <br>
    </div>'''
    
    soup2 = BeautifulSoup(html2)
    
    >>> print ' '.join(soup1.stripped_strings)
    Informácie pre záujemcu: Výberový pohovor je potrebné vopred dojednať telefonicky
    
    >>> print ' '.join(soup2.stripped_strings)
    Informácie pre záujemcu: Výberový pohovor je potrebné vopred dojednať telefonicky
    
    >>> ' '.join(soup1.stripped_strings) == ' '.join(soup2.stripped_strings)
    True
    

    最后一行显示,虽然输入中的空格(&lt;br&gt;)不同,但文字是一样的。

    【讨论】:

      【解决方案2】:

      我认为 bs4 的 get_text 方法应该可以正常工作。然后,您可以使用一些正则表达式处理结果以删除任何多余的空格。

      import re
      
      div = soup.find('div', class_='textNahlad')
      
      text = div.get_text()
      # '\nInformácie pre záujemcu:\n\n\n\nVýberový pohovor je potrebné vopred dojednať telefonicky\n\n'
      
      result = re.sub(r'\s+', ' ', text).strip()
      # 'Informácie pre záujemcu: Výberový pohovor je potrebné vopred dojednať telefonicky'
      

      【讨论】:

        【解决方案3】:

        这样做:

        #! /usr/bin/env python
        # -*- coding: utf-8 -*-
        
        content = """
        <div class="textNahlad">
                 <b>Informácie pre záujemcu:</b>
                 <br>
                 <br>
                 <br>
                 <i>Výberový pohovor je potrebné vopred dojednať telefonicky</i>
                 <br>
        </div>
        """
        from bs4 import BeautifulSoup
        soup = BeautifulSoup(content)
        for string in soup.strings:
            if string.strip():
                print string.strip(),
        

        【讨论】:

        • 这会为 2 个 HTML 样本产生不同的结果 - “záujemcu:”和“Výberový”之间的空格数不同。您可以使用' '.join([s.strip() for s in soup.strings if s.strip()]) 来纠正它,但它很笨拙。
        【解决方案4】:

        当然,您确实应该使用适当的解析库(如 lxml 或 BeautifulSoup)来执行此操作,但可以使用几个正则表达式和字符串方法轻松完成。

        #! /usr/bin/env python
        # -*- coding: utf_8 -*- 
        
        import re
        
        src = '''
        <div class="textNahlad">
             <i>Informácie pre záujemcu:</i>
             <br>
            Výberový pohovor je potrebné vopred dojednať telefonicky
             <br>
        </div>
        <div class="textNahlad">
                 <b>Informácie pre záujemcu:</b>
                 <br>
                 <br>
                 <br>
                <i>Výberový pohovor je potrebné vopred dojednať telefonicky</i>
                 <br>
        </div>
        '''
        
        flags = re.DOTALL
        #Capture div content
        pdiv = re.compile(r'<div [^>]*?>(.*?)</div>', flags)
        #Find remaining tags
        ptag = re.compile(r'<[^>]*?>', flags)
        
        def main():
            divs = pdiv.findall(src)
            for i, d in enumerate(divs):
                parts = [s.strip() for s in ptag.split(d)]
                text = ' '.join(s for s in parts if s)
                print "%d:\n%s\n" % (i, text) 
        
        
        if __name__ == "__main__":
            main()
        

        输出

        0:
        Informácie pre záujemcu: Výberový pohovor je potrebné vopred dojednať telefonicky
        
        1:
        Informácie pre záujemcu: Výberový pohovor je potrebné vopred dojednať telefonicky
        

        此代码不处理 HTML 实体,但添加起来并不难。

        【讨论】:

          猜你喜欢
          • 2019-11-16
          • 1970-01-01
          • 1970-01-01
          • 2016-01-12
          • 2017-08-13
          • 2012-03-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多