2017-01-13 54 views
1

我试图用Beautifuloup来提取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标记中的所有内容。

我不确定如何解决此问题。也许先递归地从孩子中删除文本?还是有更简单的方法我错过了?

回答

1

你不能简单的复位.string为空字符串,因为如果元素与文本一个孩子,就像在你的榜样tr元素,你会无意中删除从树中td元素。

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

我不记得一个内置的方式来获得HTML树结构没有数据BeautifulSoup - 我会用下面的办法:

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

在这里,我们重置.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> 
+0

啊,谢谢你的解释,尤其是对准确描述为什么我原来的做法是有缺陷的。 –

+0

@ hannahbanana2.0高兴地帮助,我试图看看是否有一个更美丽的方式来解决你的问题......看着'lxml'和'lxml.objectify' .. – alecxe

+0

@ hannahbanana2.0 btw,这里是一个[很相关的话题](http://stackoverflow.com/questions/24640959/get-a-structure-of-html-code)与另一种方法 - 可能比我们在这里做的更简单。 – alecxe