繁体   English   中英

美丽的汤提取物标签删除文本

[英]beautiful soup extract tags delete text

我正在尝试使用Beautifuloup提取html标签并删除文本。 例如,使用以下html:

html_page = """
<html>
<body>
<table>
<tr class=tb1><td>Lorem Ipsum dolor Sit amet</td></tr>
<tr class=tb1><td>Consectetuer adipiscing elit</td></tr>
<tr><td>Aliquam Tincidunt mauris eu Risus</td></tr>
<tr><td>Vestibulum Auctor Dapibus neque</td></tr>
</table>
</body>
</html>
"""

理想的结果是:

<html>
<body>
<table>
<tr><td></td></tr>
<tr><td></td></tr>
<tr><td></td></tr>
<tr><td></td></tr>
</table>
</body>
</html>

到目前为止,这是我得到的:

def get_tags(soup):
    copy_soup = soup
    for tag in copy_soup.findAll(True):
        tag.attrs = {} # removes attributes of a tag
        tag.string = ''

    return copy_soup

print get_tags(soup)

使用tag.attrs = {}可删除所有标签属性。 但是当我尝试使用tag.string或tag.clear()时,我只剩下<html></html> 我了解发生的情况可能是在使用tag.stringtag.clear()的第一次迭代中删除了html标签中的所有内容。

我不确定该如何解决。 也许首先递归地从子级删除文本? 还是我缺少一种更简单的方法?

您不能简单地将.string重置为空字符串,因为如果元素中有一个带有文本的子元素(例如您的示例中的tr元素),则会无意中从树中删除td元素。

您不能使用.clear()因为它.clear()递归地删除所有子节点。

我不记得在BeautifulSoup没有数据时获取HTML树结构的内置方法-我将使用以下方法:

for elm in soup.find_all():
    if not elm.find(recursive=False):  # if not children
        elm.string = ''
    elm.attrs = {}

在这里,仅当没有子.string才重置.string

演示:

>>> from bs4 import BeautifulSoup
>>> 
>>> html_page = """
... <html>
... <body>
... <table>
... <tr class=tb1><td>Lorem Ipsum dolor Sit amet</td></tr>
... <tr class=tb1><td>Consectetuer adipiscing elit</td></tr>
... <tr><td>Aliquam Tincidunt mauris eu Risus</td></tr>
... <tr><td>Vestibulum Auctor Dapibus neque</td></tr>
... </table>
... </body>
... </html>
... """
>>> 
>>> soup = BeautifulSoup(html_page, "html.parser")
>>> for elm in soup.find_all():
...     if not elm.find(recursive=False):
...         elm.string = ''
...     elm.attrs = {}
... 
>>> print(soup.prettify())
<html>
 <body>
  <table>
   <tr>
    <td>
    </td>
   </tr>
   <tr>
    <td>
    </td>
   </tr>
   <tr>
    <td>
    </td>
   </tr>
   <tr>
    <td>
    </td>
   </tr>
  </table>
 </body>
</html>

实际上,我能够通过递归更新子标签来删除文本。 您还可以在递归中更新其属性。

from bs4 import BeautifulSoup
from bs4.element import NavigableString

def delete_displayed_text(element):
    """
    delete displayed text from beautiful soup tag element object recursively
    :param element: beautiful soup tag element object
    :return: beautiful soup tag element object
    """
    new_children = []
    for child in element.contents:
        if not isinstance(child, NavigableString):
            new_children.append(delete_displayed_text(child))
    element.contents = new_children
    return element

if __name__ =='__main__':
    html_code_sample = '<div class="hello">I am not supposed to be displayed<a>me neither</a></div>'
    soup = BeautifulSoup(html_code_sample, 'html.parser')
    soup = delete_displayed_text(soup)
    cleaned_soup = BeautifulSoup(str(soup), 'html.parser')
    print(cleaned_soup.getText())

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM