【问题标题】:python alexa result parsing with lxml.etree使用 lxml.etree 解析 python alexa 结果
【发布时间】:2014-06-24 09:14:07
【问题描述】:

我正在使用 aws 的 alexa api,但我发现很难解析结果以获得我想要的结果

alexa api 返回一个对象树<type 'lxml.etree._ElementTree'>

我用这段代码来打印树

from lxml import etree
root = tree.getroot()
print etree.tostring(root)

我得到下面的 xml

<aws:UrlInfoResponse xmlns:aws="http://alexa.amazonaws.com/doc/2005-10-05/"><aws:Response xmlns:aws="http://awis.amazonaws.com/doc/2005-07-11"><aws:OperationRequest><aws:RequestId>ccf3f263-ab76-ab63-db99-244666044e85</aws:RequestId></aws:OperationRequest><aws:UrlInfoResult><aws:Alexa>

  <aws:ContentData>
    <aws:DataUrl type="canonical">google.com/</aws:DataUrl>
    <aws:SiteData>
      <aws:Title>Google</aws:Title>
      <aws:Description>Enables users to search the world's information, including webpages, images, and videos. Offers unique features and search technology.</aws:Description>
      <aws:OnlineSince>15-Sep-1997</aws:OnlineSince>
    </aws:SiteData>
    <aws:LinksInCount>3453627</aws:LinksInCount>
  </aws:ContentData>
  <aws:TrafficData>
    <aws:DataUrl type="canonical">google.com/</aws:DataUrl>
    <aws:Rank>1</aws:Rank>
  </aws:TrafficData>
</aws:Alexa></aws:UrlInfoResult><aws:ResponseStatus xmlns:aws="http://alexa.amazonaws.com/doc/2005-10-05/"><aws:StatusCode>Success</aws:StatusCode></aws:ResponseStatus></aws:Response></aws:UrlInfoResponse>

我使用root.find('LinksInCount').text 来获取元素的值,但它不起作用。

我想知道如何获取aws:LinksInCount的文本3453627

【问题讨论】:

    标签: python amazon-web-services lxml xml.etree


    【解决方案1】:

    你遇到了两个挑战:

    • 使用命名空间的 XML
    • 两个命名空间共享相同的命名空间前缀

    具有 2 个不同命名空间的重复使用前缀的 XML 文档

    您会看到"aws:" 前缀,但它用于两个不同的命名空间:

    xmlns:aws="http://alexa.amazonaws.com/doc/2005-10-05/"
    xmlns:aws="http://awis.amazonaws.com/doc/2005-07-11"
    

    在 XML 中使用相同的命名空间前缀是完全合法的。规则是,后一个有效。

    xmlstr = """
    <?xml version="1.0"?>
    <aws:UrlInfoResponse xmlns:aws="http://alexa.amazonaws.com/doc/2005-10-05/">
      <aws:Response xmlns:aws="http://awis.amazonaws.com/doc/2005-07-11">
        <aws:OperationRequest>
          <aws:RequestId>ccf3f263-ab76-ab63-db99-244666044e85</aws:RequestId>
        </aws:OperationRequest>
        <aws:UrlInfoResult>
          <aws:Alexa>
            <aws:ContentData>
              <aws:DataUrl type="canonical">google.com/</aws:DataUrl>
              <aws:SiteData>
                <aws:Title>Google</aws:Title>
                <aws:Description>Enables users to search the world's information, including webpages, images, and videos. Offers unique features and search technology.</aws:Description>
                <aws:OnlineSince>15-Sep-1997</aws:OnlineSince>
              </aws:SiteData>
              <aws:LinksInCount>3453627</aws:LinksInCount>
            </aws:ContentData>
            <aws:TrafficData>
              <aws:DataUrl type="canonical">google.com/</aws:DataUrl>
              <aws:Rank>1</aws:Rank>
            </aws:TrafficData>
          </aws:Alexa>
        </aws:UrlInfoResult>
        <aws:ResponseStatus xmlns:aws="http://alexa.amazonaws.com/doc/2005-10-05/">
          <aws:StatusCode>Success</aws:StatusCode>
        </aws:ResponseStatus>
      </aws:Response>
    </aws:UrlInfoResponse>
    """
    

    下一个挑战是,如何搜索命名空间元素。

    我更喜欢使用xpath,为此,您可以在xpath 表达式中使用您喜欢的任何命名空间,但您必须告诉xpath 调用这些前缀的含义。这是由namespacesdictionary 完成的:

    from lxml import etree
    doc = etree.fromstring(xmlstr.strip())
    
    namespaces = {"aws": "http://awis.amazonaws.com/doc/2005-07-11"}
    texts = doc.xpath("//aws:LinksInCount/text()", namespaces=namespaces)
    print texts[0]
    

    【讨论】:

    • 嗨@Jan-Vlcinsky,你知道如何解析“TrafficData”下的“DataUrl”吗?而不是在 contentData 下找到一个?谢谢!
    • @Yaeli778 呢doc.xpath("//aws:TrafficData/aws:DataUrl/text()", namespaces=namespaces)[0]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-09
    相关资源
    最近更新 更多