Парсинг xml с этри - PullRequest
       14

Парсинг xml с этри

1 голос
/ 04 января 2012

Я пытаюсь проанализировать XML-ответ от API рекламы продуктов Amazon, это xml

<?xml version="1.0" ?>
    <ItemLookupResponse xmlns="http://webservices.amazon.com/AWSECommerceService/2010-11-01"> <OperationRequest>
        <HTTPHeaders>
            <Header Name="UserAgent" Value="TSN (Language=Python)"></Header>
        </HTTPHeaders>
        <RequestId>96ef9bc3-68a8-4bf3-a2c7-c98b8aeae00f</RequestId>
        <Arguments>
            <Argument Name="Operation" Value="ItemLookup"></Argument>
            <Argument Name="Service" Value="AWSECommerceService"></Argument>
            <Argument Name="Signature" Value="gjc4wRNum3YT82app1d06vMIDM7v44fOmZTP8Uh3LqE="></Argument><Argument Name="AssociateTag" Value="sneakick-20"></Argument>
            <Argument Name="Version" Value="2010-11-01"></Argument>
            <Argument Name="ItemId" Value="810056013349,810056013264"></Argument>
            <Argument Name="IdType" Value="UPC"></Argument>
            <Argument Name="AWSAccessKeyId" Value="AKIAIFMUMJLJOOINRVRA"></Argument>
            <Argument Name="Timestamp" Value="2012-01-03T21:26:39Z"></Argument>
            <Argument Name="ResponseGroup" Value="ItemIds"></Argument>
            <Argument Name="SearchIndex" Value="Apparel"></Argument>
        </Arguments>
       <RequestProcessingTime>0.0595830000000000</RequestProcessingTime>
      </OperationRequest>
      <Items>
          <Request>
              <IsValid>True</IsValid>
              <ItemLookupRequest>
                  <IdType>UPC</IdType>
                  <ItemId>810056013349</ItemId>
                  <ItemId>810056013264</ItemId>
                  <ResponseGroup>ItemIds</ResponseGroup>
                  <SearchIndex>Apparel</SearchIndex>
                  <VariationPage>All</VariationPage>
              </ItemLookupRequest>
          </Request>
          <Item>
              <ASIN>B000XR4K6U</ASIN>
          </Item>
          <Item>
              <ASIN>B000XR2UU8</ASIN>
          </Item>
       </Items>
    </ItemLookupResponse>

Все, что меня интересует, это теги Item внутри Items, так что в основном все, что xml было возвращеноамазонка в строке, которую я проанализировал следующим образом:

from xml.etree.ElementTree import fromstring

response = "xml string returned by amazon"
parsed = fromstring(response)
items = parsed[1] # This is how i get the Items element

# These were my attempts at getting the Item element
items.find('Item')
items.findall('Item')

items является элементом Items, но пока безуспешно, он продолжает возвращать None / Empty, я что-то пропустил, или есть другой путьоб этом?

Ответы [ 2 ]

4 голосов
/ 04 января 2012

Это проблема пространства имен. Это работает:

from xml.etree import ElementTree as ET

XML = """<?xml version="1.0" ?>
    <ItemLookupResponse xmlns="http://webservices.amazon.com/AWSECommerceService/2010-11-01"> 
      <OperationRequest>
        <HTTPHeaders>
            <Header Name="UserAgent" Value="TSN (Language=Python)"></Header>
        </HTTPHeaders>
        <RequestId>96ef9bc3-68a8-4bf3-a2c7-c98b8aeae00f</RequestId>
        <Arguments>
            <Argument Name="Operation" Value="ItemLookup"></Argument>
            <Argument Name="Service" Value="AWSECommerceService"></Argument>
            <Argument Name="Signature" Value="gjc4wRNum3YT82app1d06vMIDM7v44fOmZTP8Uh3LqE="></Argument>
            <Argument Name="AssociateTag" Value="sneakick-20"></Argument>
            <Argument Name="Version" Value="2010-11-01"></Argument>
            <Argument Name="ItemId" Value="810056013349,810056013264"></Argument>
            <Argument Name="IdType" Value="UPC"></Argument>
            <Argument Name="AWSAccessKeyId" Value="AKIAIFMUMJLJOOINRVRA"></Argument>
            <Argument Name="Timestamp" Value="2012-01-03T21:26:39Z"></Argument>
            <Argument Name="ResponseGroup" Value="ItemIds"></Argument>
            <Argument Name="SearchIndex" Value="Apparel"></Argument>
        </Arguments>
       <RequestProcessingTime>0.0595830000000000</RequestProcessingTime>
      </OperationRequest>
      <Items>
          <Request>
              <IsValid>True</IsValid>
              <ItemLookupRequest>
                  <IdType>UPC</IdType>
                  <ItemId>810056013349</ItemId>
                  <ItemId>810056013264</ItemId>
                  <ResponseGroup>ItemIds</ResponseGroup>
                  <SearchIndex>Apparel</SearchIndex>
                  <VariationPage>All</VariationPage>
              </ItemLookupRequest>
          </Request>
          <Item>
              <ASIN>B000XR4K6U</ASIN>
          </Item>
          <Item>
              <ASIN>B000XR2UU8</ASIN>
          </Item>
       </Items>
    </ItemLookupResponse>"""

NS = "{http://webservices.amazon.com/AWSECommerceService/2010-11-01}"

doc = ET.fromstring(XML)
Item_elems = doc.findall(".//" + NS + "Item")  # All Item elements in document

print Item_elems

Выход:

[<Element '{http://webservices.amazon.com/AWSECommerceService/2010-11-01}Item' at 0xbf0c50>, 
<Element '{http://webservices.amazon.com/AWSECommerceService/2010-11-01}Item' at 0xbf0cd0>]

Вариация ближе к вашему собственному коду:

NS = "{http://webservices.amazon.com/AWSECommerceService/2010-11-01}"
doc = ET.fromstring(XML)
items = doc[1]                           # Items element

first_item = items.find(NS + 'Item')     # First direct Item child
all_items =  items.findall(NS + 'Item')  # List of all direct Item children
1 голос
/ 04 января 2012

Проблема пространства имен.

Вы можете поместить пространство имен перед всеми вашими предметами, как указано в первом ответе на этот вопрос или на этот вопрос . Возможно, более простое решение - игнорировать пространство имен с помощью быстрого взлома, подобного следующему:

xml_hacked_namespace = raw_xml.replace(' xmlsn=', ' xmlnamespace=')
doc = fromstring(xml_hacked_namespace)
item_list = doc.findall('.//Item')

Если вы обнаружите, что вы много работаете с xml, вас также может заинтересовать lxml . Это быстрее и предоставляет несколько дополнительных методов, которые некоторые находят приятными.

...