2012-01-03 2 views
1

Я пытаюсь разобрать ответ XML от Амазонки рекламы продукта API, это XMLСинтаксический XML с etree

<?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> 

Все я заинтересован в это элемент метки внутри предметов, поэтому в основном все, что 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, но до сих пор не увенчались успехом, он постоянно возвращается None/Empty, им я что-то отсутствует, или есть другой путь об этом ?

+1

Было бы полезно, если бы вы указали свою часть кода разбора! –

+0

Отредактировал вопрос: P – Paulo

ответ

4

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

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 
+0

большое спасибо: P – Paulo

+0

Хотел бы я поддержать это +10. Просто из-за последнего образца кода. Хорошие примеры как-то очень трудно найти. – sjas

1

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

Вы можете разместить пространство имен перед всеми вашими товарами, как указано в первом ответе, либо this question, либо this question. Возможно, более простым решением является игнорировать пространство имен с быстрым хака, как это:

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

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

Смежные вопросы