python - Beautifulsoup 删除重复的父标签和子标签

标签 python html beautifulsoup

我正在尝试从 BeautifulSoup 的输出中删除围绕文本的重复标签。

scrape_selected_tagsbs4.element.ResultSet 的 BeautifulSoup 类型其输出:

[<img/>]
[<img/> <a>1</a> <a>1</a> <a><b>1</b></a> <a><b>1</b><c>3</c></a> <img/>]

我尝试像这样删除重复项:

check_list = []

for i in scrape_selected_tags:
    if i not in check_list:
        check_list.append(i)
    else:
        "".join(re.findall("<\w+>|</\w+>|<\w+/>", str(i)))

print check_list

输出:

[<img/>]
[<img/>, <a>1</a>, <a><b>1</b></a>, <a><b>1</b><c>3</c></a>]

删除重复的<a>1</a><img>来自 scrape_selected_tags 中的第二个元素。但是,我想保留 <img>标签,因为它不包围文本,我想保留标签 <a></a>演示 <a>1</a>最初就在那里,即输出:

[<img/>]
[<img/>, <a>1</a>, <a></a>, <a><b>1</b></a>, <a><b>1</b><c>3</c></a>, <img/>]

如何修改我的代码来执行此操作?

我还想将其应用于重复的子标签。我最终想要的输出如下,其中 <b>1</b>从最后一个元素中删除,但 <b></b>标签仍然存在。

[<img/>]
[<img/>, <a>1</a>, <a></a>, <a><b>1</b></a>, <a><b></b><c>3</c></a>, <img/>]

我尝试循环 check_list使用新的 for 循环:

for i in [child for parent in check_list for child in parent.find_all()]:
    print i

这将检索所有子标签。使用与父标签相同的方法删除它们是行不通的。我无法使用set函数,因为我想保留不包含字符串的标签,例如 <img> 。这就是我使用正则表达式的原因。

提前谢谢您。

最佳答案

关于问题的第一部分,您可以使用标签名称列表来保留和检查 Tag.name字符串包含在列表中。
对于重复的标签,您可以创建新的 Tag没有文本内容的对象。

from bs4 import BeautifulSoup, Tag

scrape_selected_tags = ['<img/>', '<a>1</a>', '<a>1</a>', '<a><b>1</b></a>', '<a><b>1</b><c>3</c></a>', '<img/>']
scrape_selected_tags = [BeautifulSoup(tag, 'html.parser').find() for tag in scrape_selected_tags]

keep = ['img']
check_list = []

for i in scrape_selected_tags:
    if i not in check_list or i.name in keep:
        check_list.append(i)
    else:
        check_list.append(Tag(name=i.name))

print check_list

[<img/>, <a>1</a>, <a></a>, <a><b>1</b></a>, <a><b>1</b><c>3</c></a>, <img/>]

<小时/>

将这些规则应用于嵌套标签有点困难。您必须将 check_list 中的项目展平为了检查嵌套在新项目中的任何标签是否包含在列表中已有的任何标签中。

如果是,则创建一个新的空 Tag并使用 replace_with 在将项目添加到列表之前替换旧标签的方法。

for i in scrape_selected_tags:
    tag = i if i not in check_list or i.name in keep else Tag(name=i.name)
    for child in tag.find_all():
        if child in [ct for pt in check_list for ct in [pt] + pt.find_all()]:
            child.replace_with(Tag(name=child.name))
    check_list.append(tag)

print check_list

[<img/>, <a>1</a>, <a></a>, <a><b>1</b></a>, <a><b></b><c>3</c></a>, <img/>]

关于python - Beautifulsoup 删除重复的父标签和子标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48154581/

相关文章:

python - 如何在scrapy spider中传递用户定义的参数

python - 按类别和点大小划分的 Pandas 散点图

python - 获取连续n次出现的值

python - 我正在使用 django 和 beautiful soup 尝试获取链接,但它不起作用

python - 网页抓取 bs4,无法弄清楚如何获得结果

python - 从 Python 中的字符串推断适当的数据库类型声明

javascript - 在井内悬停时向 Bootstrap 缩略图图像添加叠加层

javascript - 使用 Javascript 切换的导航栏汉堡的响应式下拉菜单适用于 Chrome、Firefox,但不适用于 Safari

html - 图片和菜单栏周围的空间

python - 当将 python 脚本作为 cron 选项卡运行时,如何启用本地模块?