Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 美丽的汤提取标签删除文本_Python_Html_Web Scraping_Beautifulsoup - Fatal编程技术网

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

Python 美丽的汤提取标签删除文本,python,html,web-scraping,beautifulsoup,Python,Html,Web Scraping,Beautifulsoup,我正在尝试使用BeautifulUp提取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>&l

我正在尝试使用BeautifulUp提取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>
"""
使用tag.attrs={}可以删除所有标记属性。但是当我尝试使用tag.string或tag.clear()时,我只剩下
。我知道可能是在第一次迭代中使用
tag.string
tag.clear()
删除html标记中的所有内容


我不知道如何补救。也许先从子对象递归删除文本?或者我缺少了一种更简单的方法吗?

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

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

我不记得有什么内置方法可以在没有
BeautifulSoup
中的数据的情况下获取HTML树结构-我会使用以下方法:

for elm in soup.find_all():
    if not elm.find(recursive=False):  # if not children
        elm.string = ''
    elm.attrs = {}
这里我们仅在没有子项的情况下重置
.string

演示:

>>来自bs4导入组
>>> 
>>>html_page=“”
... 
... 
... 
…Lorem Ipsum dolor Sit amet
…奉献的精英
..............毛里斯·尤里索斯
…前庭拍卖人Dapibus neque
... 
... 
... 
... """
>>> 
>>>soup=BeautifulSoup(html_页面,“html.parser”)
>>>对于汤中的榆树。查找所有()
...     如果不是elm.find(recursive=False):
...         elm.string=''
...     elm.attrs={}
... 
>>>打印(soup.prettify())

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

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

我不记得有什么内置方法可以在没有
BeautifulSoup
中的数据的情况下获取HTML树结构-我会使用以下方法:

for elm in soup.find_all():
    if not elm.find(recursive=False):  # if not children
        elm.string = ''
    elm.attrs = {}
这里我们仅在没有子项的情况下重置
.string

演示:

>>来自bs4导入组
>>> 
>>>html_page=“”
... 
... 
... 
…Lorem Ipsum dolor Sit amet
…奉献的精英
..............毛里斯·尤里索斯
…前庭拍卖人Dapibus neque
... 
... 
... 
... """
>>> 
>>>soup=BeautifulSoup(html_页面,“html.parser”)
>>>对于汤中的榆树。查找所有()
...     如果不是elm.find(recursive=False):
...         elm.string=''
...     elm.attrs={}
... 
>>>打印(soup.prettify())

实际上,我可以通过递归更新标记children的来删除文本。您还可以在递归中更新它们的属性

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())
从bs4导入美化组
从bs4.element导入NavigableString
def delete_显示的_文本(元素):
"""
递归删除Beauty soup标记元素对象中显示的文本
:param元素:美丽的汤标记元素对象
:return:Beauty soup标记元素对象
"""
新子女=[]
对于element.contents中的子元素:
如果不存在(子项、导航提示):
新建子项。追加(删除显示的子项文本)
element.contents=新的子元素
返回元素
如果“名称”=“\uuuuuuuu主要”:
html\u code\u sample='我也不应该被显示'
soup=BeautifulSoup(html\u代码\u示例'html.parser')
soup=删除\u显示的\u文本(soup)
cleaned_soup=BeautifulSoup(str(soup),'html.parser')
打印(已清理的\u soup.getText())

实际上,我可以通过递归更新标记children的来删除文本。您还可以在递归中更新它们的属性

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())
从bs4导入美化组
从bs4.element导入NavigableString
def delete_显示的_文本(元素):
"""
递归删除Beauty soup标记元素对象中显示的文本
:param元素:美丽的汤标记元素对象
:return:Beauty soup标记元素对象
"""
新子女=[]
对于element.contents中的子元素:
如果不存在(子项、导航提示):
新建子项。追加(删除显示的子项文本)
element.contents=新的子元素
返回元素
如果“名称”=“\uuuuuuuu主要”:
html\u code\u sample='我也不应该被显示'
soup=BeautifulSoup(html\u代码\u示例'html.parser')
soup=删除\u显示的\u文本(soup)
cleaned_soup=BeautifulSoup(str(soup),'html.parser')
打印(已清理的\u soup.getText())

啊,谢谢你的解释,特别是感谢你准确地描述了我最初的方法有缺陷的原因。@Hannahbana2.0很高兴能提供帮助,我正在尝试看看是否有更漂亮的方法来解决你的问题。
lxml
lxml.objectify
。@Hannahbana2.0 btw,这是一个有另一种方法的例子——可能比我们现在所做的要简单。哦,见鬼。在创建我自己的帖子之前,我在这里搜索类似的问题时,并没有看到那个帖子。谢谢分享。@hannahbana2.0好的,我认为
lxml.objectify
在这里没有帮助。至少它看起来并不比BeautifulSoup更简单。可能是我遗漏了一些简单的东西。啊,谢谢你的解释,特别是感谢你准确地描述了我最初的方法有缺陷的原因。@Hannahbana2.0很高兴能提供帮助,我正在尝试看看是否有更漂亮的方法来解决你的问题。
lxml
lxml.objectify
。@Hannahbana2.0 btw,这是一个有另一种方法的例子——可能比我们现在所做的要简单。哦,见鬼。在创建我自己的帖子之前,我在这里搜索类似的问题时,并没有看到那个帖子。Tha
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())