使用BeautifulSoup

时间:2015-07-25 00:00:18

标签: python xml python-2.7 xml-parsing 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?谢谢你的时间。

1 个答案:

答案 0 :(得分:2)

在进行3次更改后,它对我有用:

  • 0)我使用的是bs4(这是我安装的唯一版本)

  • 1)setContentView(R.layout.activity_login);代替BeautifulSoup(xmldata, features="xml")BeautifulStoneSoup(xmldata)在bs4中折旧

  • 2)我将BeautifulStoneSoup更改为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