[英]Python-Beautiful Soup How to get tags and texts from a xml file even not knowing all the names of the tags
我有一个这样的xml文件:
<a>
<b>1</b>
<c>2</c>
<d>
<e>3</e>
</d>
</a>
<a>
<c>4</c>
<f value ="something">5</f>
<g value = "other"></g>
</a>
我想要一个带有标签和文本的字典列表。 例如:
[{'b':1, 'c':2, 'e':3}, {'c':4, 'f value="something"':5, 'g value = "other"':None}]
这是一个很大的 xml 文件,它不是标准的,所以我只知道<a>
存在并且我想要这个标签中的所有信息。
我已经尝试过 Beautiful Soup 4,但我只能检索文本部分。
我的代码
def ProcessXml(xmlFile):
infile = open(xmlFile, 'r')
contents = infile.read()
soup = BeautifulSoup(contents,'xml')
units = soup.find_all('a')
unitsList = []
for i in units:
resultType = i.text,i.next_sibling
resultType = resultType[0].splitlines()
for j in resultType:
if j == '':
resultType.remove(j)
unitsList.append((resultType))
return unitsList
我的输出:
[['1','2','3'],['4','5']]
这是非常糟糕的代码,但可以完成工作:
def len_descendant(desc):
counter = 0
try:
for i in desc.descendants:
if i!='' and i !='\n':
counter += 1
except Exception:
pass
return counter
def ProcessXml():
infile = open("xmlfile.xml", 'r')
contents = infile.read()
soup = BeautifulSoup(contents,'lxml')
units = soup.find_all('a')
unitsList = []
for i in units:
this_dict = {}
for desc in i.descendants:
print desc, len_descendant(desc)
try:
if desc.has_attr('value'):
has_attribute = True
except Exception:
has_attribute = False
if len_descendant(desc)==1 or has_attribute:
if desc.has_attr('value'):
key = desc.name + " " + desc.attrs.keys()[0] + '=\"' + desc.attrs.values()[0] + '\"'
else:
key = desc.name
try:
value = int(desc.text)
except Exception:
value = None
this_dict[key] = value
unitsList.append(this_dict)
return unitsList
my_dict = ProcessXml()
结果是:
[{'c': 2, 'b': 1, 'e': 3}, {'f value="something"': 5, 'c': 4, 'g value="other"': 1}]
注意:正如 MYGz 提到的, 'g value = "other"'}]
部分无效,所以我这是我尝试使用该功能的 XML 文件:
<a>
<b>1</b>
<c>2</c>
<d>
<e>3</e>
</d>
</a>
<a>
<c>4</c>
<f value ="something">5</f>
<g value = "other">1</g>
</a>
def len_descendant(desc):
counter = 0
try:
for i in desc.descendants:
#print (i)
if i!='' and i !='\n':
counter += 1
except Exception:
pass
return counter
def ProcessXmlTwo(fileName):
infile = open(fileName, 'r')
contents = infile.read()
soup = BeautifulSoup(contents,'xml')
units = soup.find_all('a')
#print (units)
unitsList = []
for i in units:
this_dict = {}
for desc in i.descendants:
flagNoKey = False
if len_descendant(desc)==1 or 'value="true"/>' in str(desc) or 'value="false"/>' in str(desc):
if desc.has_attr('value'):
#print (desc.name)
key = desc.name + " " + list(desc.attrs.keys())[0] + '=\"' + list(desc.attrs.values())[0] + '\"'
elif 'value="true"/>' in str(desc) or 'value="false"/>' in str(desc):
flagNoKey = True
key = desc.name + " " + list(desc.attrs.keys())[0] + '=\"' + list(desc.attrs.values())[0] + '\"'
else:
key = desc.name
if flagNoKey == False:
this_dict[key] = desc.text
else:
this_dict[key] = "None"
unitsList.append(this_dict)
return unitsList
这是我将使用的代码。 这是对@Stergios 编写的代码的改编。 (适用于python 3)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.