请考虑这种方法:
from bs4 import BeautifulSoup
with open('test.xml') as raw_resuls:
results = BeautifulSoup(raw_resuls, 'lxml')
for element in results.find_all("tag"):
for stat in element.find_all("stat"):
print(stat['pass'])
您的解决方案的问题是 pass 包含在 stat 中,而不是在您搜索它的 tag 中。
此解决方案搜索所有tag,并在这些tag 中搜索stat。从这些结果中,它得到通过。
对于 XML 文件
<tag>
<stat fail="0" pass="1">TR=111111 Sandbox=3000613</stat>
<stat fail="0" pass="1">TR=121212 Sandbox=3000618</stat>
<stat fail="0" pass="1">TR=999999 Sandbox=3000617</stat>
</tag>
上面的脚本得到输出
1
1
1
加法
由于某些细节似乎仍不清楚(请参阅 cmets),请考虑使用 BeautifulSoup 的完整解决方法来获得您想要的一切。如果您遇到性能问题,这种使用字典作为列表元素的解决方案可能并不完美。但是由于您似乎在使用 Python 和 Soup 时遇到了一些麻烦,所以我认为我可以通过名称而不是索引来访问所有相关信息,从而尽可能简单地创建这个示例。
from bs4 import BeautifulSoup
# Parses a string of form 'TR=abc123 Sandbox=abc123' and stores it in a dictionary with the following
# structure: {'TR': abc123, 'Sandbox': abc123}. Returns this dictionary.
def parseTestID(testid):
dict = {'TR': testid.split(" ")[0].split("=")[1], 'Sandbox': testid.split(" ")[1].split("=")[1]}
return dict
# Parses the XML content of 'rawdata' and stores pass value, TR-ID and Sandbox-ID in a dictionary of the
# following form: {'Pass': pasvalue, TR': TR-ID, 'Sandbox': Sandbox-ID}. This dictionary is appended to
# a list that is returned.
def getTestState(rawdata):
# initialize parser
soup = BeautifulSoup(rawdata,'lxml')
parsedData= []
# parse for tags
for tag in soup.find_all("tag"):
# parse tags for stat
for stat in tag.find_all("stat"):
# store everthing in a dictionary
dict = {'Pass': stat['pass'], 'TR': parseTestID(stat.string)['TR'], 'Sandbox': parseTestID(stat.string)['Sandbox']}
# append dictionary to list
parsedData.append(dict)
# return list
return parsedData
你可以使用上面的脚本做任何你想做的事情(例如打印出来)
# open file
with open('test.xml') as raw_resuls:
# get list of parsed data
data = getTestState(raw_resuls)
# print parsed data
for element in data:
print("TR = {0}\tSandbox = {1}\tPass = {2}".format(element['TR'],element['Sandbox'],element['Pass']))
输出如下所示
TR = 111111 Sandbox = 3000613 Pass = 1
TR = 121212 Sandbox = 3000618 Pass = 1
TR = 222222 Sandbox = 3000612 Pass = 1
TR = 232323 Sandbox = 3000618 Pass = 1
TR = 333333 Sandbox = 3000605 Pass = 1
TR = 343434 Sandbox = ZZZZZZ Pass = 1
TR = 444444 Sandbox = 3000604 Pass = 1
TR = 454545 Sandbox = 3000608 Pass = 1
TR = 545454 Sandbox = XXXXXX Pass = 1
TR = 555555 Sandbox = 3000617 Pass = 1
TR = 565656 Sandbox = 3000615 Pass = 1
TR = 626262 Sandbox = 3000602 Pass = 1
TR = 666666 Sandbox = 3000616 Pass = 1
TR = 676767 Sandbox = 3000599 Pass = 1
TR = 737373 Sandbox = 3000603 Pass = 1
TR = 777777 Sandbox = 3000611 Pass = 1
TR = 787878 Sandbox = 3000614 Pass = 1
TR = 828282 Sandbox = 3000600 Pass = 1
TR = 888888 Sandbox = 3000610 Pass = 1
TR = 999999 Sandbox = 3000617 Pass = 1
让我们总结一下使用的核心元素:
查找 XML 标记
要查找 XML 标记,您可以使用 soup.find("tag") 返回第一个匹配的标记或 soup.find_all("tag") 查找所有匹配的标记并将它们存储在列表中。通过遍历列表可以轻松访问单个标签。
查找嵌套标签
要查找嵌套标签,您可以再次使用find() 或find_all(),将其应用于第一个find_all() 的结果。
访问标签的内容
要访问标签的内容,请将string 应用于单个标签。比如tag = <tag>I love Soup!</tag>tag.string = "I love Soup!".
查找属性值
要获取属性的值,您可以使用下标表示法。比如tag = <tag color=red>I love Soup!</tag>tag['color']="red".
为了解析 "TR=abc123 Sandbox=abc123" 形式的字符串,我使用了常见的 Python 字符串拆分。你可以在这里阅读更多信息:How can I split and parse a string in Python?