Как получить доступ к полю XML с помощью lxml? - PullRequest
0 голосов
/ 16 декабря 2018

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>

Ответы [ 2 ]

0 голосов
/ 16 декабря 2018

Еще один способ справиться с этим - избегать использования интерфейса атрибутов flaky:

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

Используя интерфейс индексации в стиле dict, вам никогда не придется беспокоиться об именах определенных атрибутов (которые включают в себя такие распространенные слова).как items, index, keys, remove, replace, tag, set, text и values), возвращая удивительные результаты.

0 голосов
/ 16 декабря 2018

Проблема в том, что 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)
...