【问题标题】:sitemap xml parsing in python 3.xpython 3.x中的站点地图xml解析
【发布时间】:2020-09-12 02:12:20
【问题描述】:

我的xml结构如下

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">
    <url>
        <loc>hello world 1</loc>
        <image:image>
            <image:loc>this is image loc 1</image:loc>
            <image:title>this is image title 1</image:title>
        </image:image>
        <lastmod>2019-06-19</lastmod>
        <changefreq>daily</changefreq>
        <priority>0.25</priority>
    </url>
    <url>
        <loc>hello world 2</loc>
        <image:image>
            <image:loc>this is image loc 2</image:loc>
            <image:title>this is image title 2</image:title>
        </image:image>
        <lastmod>2020-03-19</lastmod>
        <changefreq>daily</changefreq>
        <priority>0.25</priority>
    </url>
</urlset>

我只想得到

hello world 1
hello world 2

我的python代码如下:

import xml.etree.ElementTree as ET
tree = ET.parse('test.xml')
root = tree.getroot()

for url in root.findall('url'):
    loc = url.find('loc').text
    print(loc)

不幸的是,它什么也没给我。

但是当我将我的 xml 更改为

<urlset>
    <url>
        <loc>hello world 1</loc>
        <lastmod>2019-06-19</lastmod>
        <changefreq>daily</changefreq>
        <priority>0.25</priority>
    </url>
    <url>
        <loc>hello world 2</loc>
        <lastmod>2020-03-19</lastmod>
        <changefreq>daily</changefreq>
        <priority>0.25</priority>
    </url>
</urlset>

它给了我正确的结果。

hello world 1
hello world 2

如何在不更改 xml 的情况下获得正确的结果?因为修改 10000+ 行文件没有任何意义。

TIA

【问题讨论】:

    标签: python python-3.x xml-sitemap


    【解决方案1】:

    您的代码的(不雅的)修复是:

    import xml.etree.ElementTree as ET
    tree = ET.parse('test.xml')
    root = tree.getroot()
    
    # In find/findall, prefix namespaced tags with the full namespace in braces
    for url in root.findall('{http://www.sitemaps.org/schemas/sitemap/0.9}url'):
        loc = url.find('{http://www.sitemaps.org/schemas/sitemap/0.9}loc').text
        print(loc)
    

    这是因为您必须使用定义 XML 的命名空间来限定标记名称。关于如何使用 findfindall 方法与命名空间的详细信息来自 Parse XML namespace with Element Tree findall

    【讨论】:

      【解决方案2】:

      如果您不想弄乱命名空间,这是一个比公认的答案更简单的解决方案,而且更优雅一点,使用通用 xpath 查询:

      import lxml.etree
      
      
      tree = lxml.etree.parse('test.xml')
      
      for url in tree.xpath("//*[local-name()='loc']/text()"):
          print(url)
      

      如果你更喜欢使用 xml 命名空间,你应该这样做:

      import lxml.etree
      
      
      tree = lxml.etree.parse('test.xml')
      
      namespaces = {
          'sitemapindex': 'http://www.sitemaps.org/schemas/sitemap/0.9',
      }
      
      for url in tree.xpath("//sitemapindex:loc/text()", namespaces=namespaces):
          print(url)
      

      如果您喜欢直接从内存而不是文件加载 xml 数据,您可以使用 lxml.etree.fromstring 代替 lxml.etree.parse。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-11
        相关资源
        最近更新 更多