【问题标题】:How to access xml field with lxml?如何使用 lxml 访问 xml 字段?
【发布时间】:2018-12-16 15:17:13
【问题描述】:

Python 3.6、Lxml、Windows 10

我快疯了。我想访问项目字段。但我总是得到错误:

AttributeError: 'cython_function_or_method' 对象没有属性'item'

我可以毫无问题地访问其他所有内容(地址字段等...)。如何访问项目字段(sku、金额等...)?

我用过这段代码:

import requests
from lxml import objectify

url = "URL_TO_XML_FILE"
xml_content = requests.get(url).text.encode('utf-8')

xml = objectify.fromstring(xml_content)

for sale in xml.response.sales.sale:
    for item in sale.items.item:
        print(item.sku)

这里是xml的开头:

<?xml version="1.0" encoding="ISO-8859-1"?>
<getnewsalesresult xmlns="https://pmcdn.priceminister.com/res/schema/getnewsales">
  <request>
    <version>2017-08-07</version>
    <user>SELLER</user>
  </request>  

  <response>
    <lastversion>2017-08-07</lastversion>
    <sellerid>95029358</sellerid>
    <sales>

      <sale>
        <purchaseid>297453287592813953</purchaseid>
        <purchasedate>15/12/2018-19:10</purchasedate>
        <deliveryinformation>
          <shippingtype>Normal</shippingtype>
          <isfullrsl>N</isfullrsl>

          <purchasebuyerlogin><![CDATA[LOGIN]]></purchasebuyerlogin>                  
          <purchasebuyeremail>EMAIL</purchasebuyeremail>        


            <deliveryaddress>
            <civility>Mme</civility>
            <lastname><![CDATA[Lastname]]></lastname>
            <firstname><![CDATA[Firstname]]></firstname>
            <address1><![CDATA[STREET]]></address1>
            <address2><![CDATA[]]></address2>
            <zipcode>13570</zipcode>
            <city><![CDATA[Paris]]></city>

            <country><![CDATA[France]]></country>
            <countryalpha2>FX</countryalpha2>

              <phonenumber1></phonenumber1>
              <phonenumber2>PHONENUMBER</phonenumber2>

            </deliveryaddress>

        </deliveryinformation>
        <items>

          <item>
            <sku><![CDATA[SKU1]]></sku>
            <advertid>411812243030</advertid>
            <advertpricelisted>
              <amount>15.99</amount>
              <currency>EUR</currency>
            </advertpricelisted>
            <itemid>551131040</itemid>
            <headline><![CDATA[HEADLINE]]></headline>
            <itemstatus><![CDATA[REQUESTED]]></itemstatus>
            <ispreorder>N</ispreorder>
            <isnego>N</isnego>
            <negotiationcomment></negotiationcomment>
            <price>
              <amount>15.99</amount>
              <currency>EUR</currency>
            </price>
            <isrsl>N</isrsl>
            <isbn></isbn>
            <ean>4363745894373857474; </ean>
            <paymentstatus><![CDATA[INCOMING]]></paymentstatus>
            <sellerscore></sellerscore>
          </item>
        </items>
      </sale>
      <sale>

【问题讨论】:

    标签: python-3.x lxml lxml.objectify


    【解决方案1】:

    问题是items其实是ObjectifiedElement的一个方法,所以表达式sale.items实际上返回的是方法,因为它有优先级。

    要获得你想要的'items'对象,你必须更明确地获得sale的属性,而不是先寻找类的方法,这是通常的python顺序。当您访问属性时,这就是 python 在后台执行的操作,您也可以这样做:

    sale.__getattr__('items')
    

    这也可以工作(它是对象属性的类字典接口):

    sale.__dict__['items']
    

    修改后的代码:

    import requests
    from lxml import objectify
    
    url = "URL_TO_XML_FILE"
    xml_content = requests.get(url).text.encode('utf-8')
    
    xml = objectify.fromstring(xml_content)
    
    for sale in xml.response.sales.sale:
        for item in sale.__dict__['items'].item:
            print(item.sku)
    

    【讨论】:

    • 非常感谢。我已经浪费了几个小时试图让它发挥作用。现在一切正常。
    【解决方案2】:

    解决这个问题的另一种方法是避免使用易碎的属性接口:

    for sale in xml['response']['sales']['sale']:
        for item in sale['items']['item']:
            print(item['sku'])
    

    使用类似dict的索引界面,您永远不必担心某些属性名称(包括itemsindexkeysremovereplacetag等常用词、settextvalues) 返回令人惊讶的结果。

    【讨论】:

      猜你喜欢
      • 2013-08-25
      • 2011-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-25
      • 2016-04-25
      相关资源
      最近更新 更多