XML 未按预期使用 BeautifulSoup 进行解析
XML not parsing as expected with BeautifulSoup
我正在尝试从网站解析 XML。如果格式不正确,我无法控制内容。 XML 数据的一个非常简化的示例如下。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<items:items itemId="1">
<parameter name="param1" value="A"/>
<parameter name="param2" value="B"/>
<product productid="test1">
<parameter name="prodinfo1" value="Q"/>
<parameter name="prodinfo2" value="R"/>
</product>
<product productid="test2">
<parameter name="prodinfo1" value="S"/>
<parameter name="prodinfo2" value="T"/>
</product>
</items:items>
<items:items itemId="2">
<parameter name="param1" value="C"/>
<parameter name="param2" value="D"/>
<product productid="test3">
<parameter name="prodinfo1" value="U"/>
<parameter name="prodinfo2" value="V"/>
</product>
<product productid="test4">
<parameter name="prodinfo1" value="W"/>
<parameter name="prodinfo2" value="X"/>
</product>
</items:items>
我使用 BeautifulSoup 3.2.1 编写了一个简短的 Python 2.7 脚本来解析 XML(我只能使用这些版本,所以不幸的是升级不是一个选项) .
from BeautifulSoup import BeautifulStoneSoup
def main():
fieldList = ('param1','param2')
prodFieldList = ('prodinfo1','prodinfo2')
xmlfile = 'test.xml'
xmldata = open(xmlfile).read()
soup = BeautifulStoneSoup(xmldata)
print soup.prettify()
for message in soup.findAll('items:items', recursive=False):
report = {}
for field in fieldList:
report[field] = '{}'.format(message.find(attrs={"name" : field})['value'])
for product in message.findAll('product', recursive=False):
prodreport = {}
for field in prodFieldList:
prodreport[field] = '{}'.format(product.find(attrs={"name" : field})['value'])
if __name__ == "__main__":
main()
由于某些原因,<product></product>
中的参数(例如 prodinfo1 和 prodinfo2)未显示。当我查看 soup.prettify()
的输出时,而不是像上面 XML 文件中显示的那样缩进,我可以看到产品参数列在 <product></product>
标签之外,因此它们的特定产品的标识丢失:
<?xml version='1.0' encoding='utf-8'?>
<items:items itemid="1">
<parameter name="param1" value="A">
</parameter>
<parameter name="param2" value="B">
<product productid="test1">
</product>
</parameter>
<parameter name="prodinfo1" value="Q">
</parameter>
<parameter name="prodinfo2" value="R">
<product productid="test2">
</product>
</parameter>
<parameter name="prodinfo1" value="S">
</parameter>
<parameter name="prodinfo2" value="T">
</parameter>
</items:items>
<items:items itemid="2">
<parameter name="param1" value="C">
</parameter>
<parameter name="param2" value="D">
<product productid="test3">
</product>
</parameter>
<parameter name="prodinfo1" value="U">
</parameter>
<parameter name="prodinfo2" value="V">
<product productid="test4">
</product>
</parameter>
<parameter name="prodinfo1" value="W">
</parameter>
<parameter name="prodinfo2" value="X">
</parameter>
</items:items>
我一直在搜索,但没有找到有同样问题的人。为什么会这样,我该怎么做才能正确解析这个 XML?谢谢你的时间。
进行 3 次更改后对我有效:
0) 我正在使用 bs4(这是我安装的唯一版本)
1) BeautifulSoup(xmldata, features="xml")
而不是 BeautifulStoneSoup(xmldata)
,BeautifulStoneSoup
在 bs4
中贬值
2)我把soup.findAll('items:items', recursive=False)
改成了soup.findAll(True, {"itemId":True}, recursive=False)
from bs4 import BeautifulSoup
xmldata = #load your data
if __name__ == "__main__":
fieldList = ('param1','param2')
prodFieldList = ('prodinfo1','prodinfo2')
soup = BeautifulSoup(xmldata, features="xml")# <- notice this
print soup.prettify(), "\n"
for message in soup.findAll(True, {"itemId":True}, recursive=False):# <- and this
report = {}
for field in fieldList:
report[field] = '{}'.format(message.find(attrs={"name" : field})['value'])
print report
for product in message.findAll('product', recursive=False):
prodreport = {}
for field in prodFieldList:
prodreport[field] = '{}'.format(product.find(attrs={"name" : field})['value'])
print prodreport
输出:
<?xml version="1.0" encoding="utf-8"?>
<items itemId="1">
<parameter name="param1" value="A"/>
<parameter name="param2" value="B"/>
<product productid="test1">
<parameter name="prodinfo1" value="Q"/>
<parameter name="prodinfo2" value="R"/>
</product>
<product productid="test2">
<parameter name="prodinfo1" value="S"/>
<parameter name="prodinfo2" value="T"/>
</product>
</items>
{'param1': 'A'}
{'param2': 'B', 'param1': 'A'}
{'prodinfo1': 'Q', 'prodinfo2': 'R'}
{'prodinfo1': 'S', 'prodinfo2': 'T'}
我正在尝试从网站解析 XML。如果格式不正确,我无法控制内容。 XML 数据的一个非常简化的示例如下。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<items:items itemId="1">
<parameter name="param1" value="A"/>
<parameter name="param2" value="B"/>
<product productid="test1">
<parameter name="prodinfo1" value="Q"/>
<parameter name="prodinfo2" value="R"/>
</product>
<product productid="test2">
<parameter name="prodinfo1" value="S"/>
<parameter name="prodinfo2" value="T"/>
</product>
</items:items>
<items:items itemId="2">
<parameter name="param1" value="C"/>
<parameter name="param2" value="D"/>
<product productid="test3">
<parameter name="prodinfo1" value="U"/>
<parameter name="prodinfo2" value="V"/>
</product>
<product productid="test4">
<parameter name="prodinfo1" value="W"/>
<parameter name="prodinfo2" value="X"/>
</product>
</items:items>
我使用 BeautifulSoup 3.2.1 编写了一个简短的 Python 2.7 脚本来解析 XML(我只能使用这些版本,所以不幸的是升级不是一个选项) .
from BeautifulSoup import BeautifulStoneSoup
def main():
fieldList = ('param1','param2')
prodFieldList = ('prodinfo1','prodinfo2')
xmlfile = 'test.xml'
xmldata = open(xmlfile).read()
soup = BeautifulStoneSoup(xmldata)
print soup.prettify()
for message in soup.findAll('items:items', recursive=False):
report = {}
for field in fieldList:
report[field] = '{}'.format(message.find(attrs={"name" : field})['value'])
for product in message.findAll('product', recursive=False):
prodreport = {}
for field in prodFieldList:
prodreport[field] = '{}'.format(product.find(attrs={"name" : field})['value'])
if __name__ == "__main__":
main()
由于某些原因,<product></product>
中的参数(例如 prodinfo1 和 prodinfo2)未显示。当我查看 soup.prettify()
的输出时,而不是像上面 XML 文件中显示的那样缩进,我可以看到产品参数列在 <product></product>
标签之外,因此它们的特定产品的标识丢失:
<?xml version='1.0' encoding='utf-8'?>
<items:items itemid="1">
<parameter name="param1" value="A">
</parameter>
<parameter name="param2" value="B">
<product productid="test1">
</product>
</parameter>
<parameter name="prodinfo1" value="Q">
</parameter>
<parameter name="prodinfo2" value="R">
<product productid="test2">
</product>
</parameter>
<parameter name="prodinfo1" value="S">
</parameter>
<parameter name="prodinfo2" value="T">
</parameter>
</items:items>
<items:items itemid="2">
<parameter name="param1" value="C">
</parameter>
<parameter name="param2" value="D">
<product productid="test3">
</product>
</parameter>
<parameter name="prodinfo1" value="U">
</parameter>
<parameter name="prodinfo2" value="V">
<product productid="test4">
</product>
</parameter>
<parameter name="prodinfo1" value="W">
</parameter>
<parameter name="prodinfo2" value="X">
</parameter>
</items:items>
我一直在搜索,但没有找到有同样问题的人。为什么会这样,我该怎么做才能正确解析这个 XML?谢谢你的时间。
进行 3 次更改后对我有效:
0) 我正在使用 bs4(这是我安装的唯一版本)
1)
BeautifulSoup(xmldata, features="xml")
而不是BeautifulStoneSoup(xmldata)
,BeautifulStoneSoup
在 bs4 中贬值
2)我把
soup.findAll('items:items', recursive=False)
改成了soup.findAll(True, {"itemId":True}, recursive=False)
from bs4 import BeautifulSoup xmldata = #load your data if __name__ == "__main__": fieldList = ('param1','param2') prodFieldList = ('prodinfo1','prodinfo2') soup = BeautifulSoup(xmldata, features="xml")# <- notice this print soup.prettify(), "\n" for message in soup.findAll(True, {"itemId":True}, recursive=False):# <- and this report = {} for field in fieldList: report[field] = '{}'.format(message.find(attrs={"name" : field})['value']) print report for product in message.findAll('product', recursive=False): prodreport = {} for field in prodFieldList: prodreport[field] = '{}'.format(product.find(attrs={"name" : field})['value']) print prodreport
输出:
<?xml version="1.0" encoding="utf-8"?>
<items itemId="1">
<parameter name="param1" value="A"/>
<parameter name="param2" value="B"/>
<product productid="test1">
<parameter name="prodinfo1" value="Q"/>
<parameter name="prodinfo2" value="R"/>
</product>
<product productid="test2">
<parameter name="prodinfo1" value="S"/>
<parameter name="prodinfo2" value="T"/>
</product>
</items>
{'param1': 'A'}
{'param2': 'B', 'param1': 'A'}
{'prodinfo1': 'Q', 'prodinfo2': 'R'}
{'prodinfo1': 'S', 'prodinfo2': 'T'}