当父标签的子标签具有某些属性值时,如何使用 BeautifulSoup 获取父标签的名称值?

Posted

技术标签:

【中文标题】当父标签的子标签具有某些属性值时,如何使用 BeautifulSoup 获取父标签的名称值?【英文标题】:How to use BeautifulSoup to get parent tag's name value when the parent tag's children has certain attribute values? 【发布时间】:2017-10-09 00:16:16 【问题描述】:

为了让这个问题更容易理解,下面是一个例子

<Tag name="Thumbnail" inline="no" nonsearchable="yes">
<Attribute>
<Attribute name="AText" Searchable="yes"></Attribute>
</Attribute>
</Tag>

<Tag name="Label" inline="no" nonsearchable="yes">
<Attribute>
<Attribute name="AText" Searchable="no"></Attribute>
</Attribute>
</Tag>

<Tag name="Image" inline="no" nonsearchable="yes">
<Attribute>
<Attribute name="BText" Searchable="yes">
</Attribute>
</Tag>

<Tag name="Wonder" inline="no" nonsearchable="yes">
<Attribute>
<Attribute name="BText" Searchable="yes"></Attribute>
</Attribute>
</Tag>

预期结果

所以在excel中,如果Attribute标签的Searchable,第一行应该是Attribute标签的name value strong> 值为“”;那么这些“合格的”Attributes标签的父标签——Tag——name value会列在下面。

目前,我只能找到所有 Tag 的 name 值,如果它是 children 的 Searchable 值为“yes”,但无法将它们归类到相应的 Attribute 标签下名称值。以下是我的初始代码:

import os, openpyxl
from bs4 import BeautifulSoup

cwd = os.getcwd()

def func(x):
    for file in os.listdir(cwd):
        if file.endswith('.xml'):
            f = open(file, encoding = 'utf=8', mode = 'r+')
            soup = BeautifulSoup(f, 'lxml')
            AttrYES = soup.find_all(attrs="Searchable": "yes")
            for items in AttrYES:
                tagName = items.parent.parent.get('name')
                print (tagName)

x = os.listdir(cwd)
func(x)

我也会尝试解决这个问题,但是为了让这个过程更快,如果您有任何想法,请提出建议。谢谢!!

【问题讨论】:

【参考方案1】:

你的代码找不到任何东西,如果你打印AttrYES,它将是[]。问题是当您使用bs4 和解析器lxml 时,所有标签和属性名称都会转换为小写,请参阅official doc。如果你打印汤,它会给你:

<html><body><tag inline="no" name="Thumbnail" nonsearchable="yes">
<attribute>
<attribute name="AText" searchable="yes"></attribute>
</attribute>
</tag>
<tag inline="no" name="Label" nonsearchable="yes">
<attribute>
<attribute name="AText" searchable="no"></attribute>
</attribute>
</tag>
<tag inline="no" name="Image" nonsearchable="yes">
<attribute>
<attribute name="BText" searchable="yes">
</attribute>
</attribute></tag>
<tag inline="no" name="Wonder" nonsearchable="yes">
<attribute>
<attribute name="BText" searchable="yes"></attribute>
</attribute>
</tag></body></html>

因此,您可以像这样修改您的代码:

import bs4
f = open('test.xml',mode = 'r+')
soup = bs4.BeautifulSoup(f, 'lxml')
AttrYES = soup.findAll(attrs='searchable': 'yes')
result = dict()
for items in AttrYES:
    result[items.get('name')] = result.get(items.get('name'),[])+[items.parent.parent.get('name')]    
print(result)

打印将是:

'AText': ['Thumbnail'], 'BText': ['Image', 'Wonder']

然后您可以将它们写入您的 excel 文件:

import xlsxwriter

workbook = xlsxwriter.Workbook('result.xlsx')
worksheet = workbook.add_worksheet()

# Write header
worksheet.write(0, 0, result.keys()[0])
worksheet.write(0, 1, result.keys()[1])

# Write data.
worksheet.write_column(1, 0, result.values()[0])
worksheet.write_column(1, 1, result.values()[1])

workbook.close()

result.xlsx 将是:

更新: 使用 openpyxl

from openpyxl import Workbook
wb = Workbook()

# grab the active worksheet
ws = wb.active

# Data can be assigned directly to cells
i,j = 1,1
for keys,values in a.items():
    ws.cell(column=i, row=1, value=keys)
    for row in range(len(values)):
        ws.cell(column=i, row=j+1, value=values[row])
        j+=1
    j=1
    i+=1
wb.save("result.xlsx")

【讨论】:

非常感谢 Tiny1 的解决方案 非常感谢 Tiny 的解决方案!是的,我可以像'AText': ['Thumbnail'], 'BText': ['Image', 'Wonder'] 这样打印结果。这很棒!现在我正在尝试使用 python 的内置模块 openpyxl。出现了一些问题:首先,python3 不允许result.values() 再有索引;其次,如果我们不知道有多少个键,我们可能需要为这些值编写一个循环。我认为循环键更容易,但对于值,我仍在尝试找出方法。如果您有任何想法,那就太好了!谢谢! :) 最新更新:我可以通过编写 for key in result.keys(): sheetOut.cell(row=1, column=r).value = key r+=1 n = 1 将密钥循环到正确的 excel 单元格上但是,如果我以相同的方式循环 value,单元格内容将是 ['Thumbnail'] 和 ['Image', 'Wonder'] 。所以仍在尝试解决这个问题。 请查看更新后的答案:1、可以在python3中使用函数items(); 2、使用for循环,查看更新后的答案。 1、python3中的for循环和函数items()可以获取字典的键和值; 2,for首先循环项目,然后在值中,另一个for循环值列表以获取每个元素,在第一个for循环中,在第一行写入键,第二个for循环,将值写入同一列但下一行。希望对您有所帮助。

以上是关于当父标签的子标签具有某些属性值时,如何使用 BeautifulSoup 获取父标签的名称值?的主要内容,如果未能解决你的问题,请参考以下文章

:9.HTML如何在网页中添加图片(img标签使用方法,以及img标签属性:altheightwidth);图片格式选择

js如何获取某id的子标签?

如何在 Java 中使用 SAX Parser 检查 xml 标签是不是具有属性?

如何查找具有特定数据属性的所有标签?

如何在 python 中读取具有特定标签属性的 xml?

javascript:仅当父元素处于活动状态且子元素具有特定类时,如何向子元素添加属性?