Разбор текста из узла XML в Python

1

Я пытаюсь извлечь URL из файла Sitemap следующим образом: https://www.bestbuy.com/sitemap_c_0.xml.gz

Я распаковал и сохранил файл.xml.gz в виде XML файла. Структура выглядит так:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xhtml="http://www.w3.org/1999/xhtml" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<url>
    <loc>https://www.bestbuy.com/</loc>
    <priority>0.0</priority>
</url>
<url>
    <loc>https://www.bestbuy.com/site/3d-printers/3d-printer-filament/pcmcat335400050008.c?id=pcmcat335400050008</loc>
    <priority>0.0</priority>
</url>
<url>
    <loc>https://www.bestbuy.com/site/3d-printers/3d-printing-accessories/pcmcat748300527647.c?id=pcmcat748300527647</loc>
    <priority>0.0</priority>
</url>

Я пытаюсь использовать ElementTree для извлечения всех URL-адресов в узлах loc в этом файле, но изо всех сил пытаюсь заставить его работать правильно.

В документации я пробую что-то вроде этого:

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

value = root.findall(".//loc")

Однако ничто не загружается в стоимость. Моя цель - извлечь все URL-адреса между узлами-узлами и распечатать их в новый плоский файл. Где я иду не так?

  • 1
    Вы не принимаете во внимание пространства имен. См. Docs.python.org/3/library/…
Теги:
python-3.x
elementtree

2 ответа

1
Лучший ответ

Мы можем перебирать URL-адреса, вставлять их в список и записывать их в файл как таковой:

from xml.etree import ElementTree as ET

tree = ET.parse('test.xml')
root = tree.getroot()

name_space = '{http://www.sitemaps.org/schemas/sitemap/0.9}'

urls = []
for child in root.iter():
    for block in child.findall('{}url'.format(name_space)):
        for url in block.findall('{}loc'.format(name_space)):
            urls.append('{}\n'.format(url.text))

with open('sample_urls.txt', 'w+') as f:
    f.writelines(urls)
  • обратите внимание, что нам нужно добавить пространство имен из открытого определения urlset для правильного анализа xml
  • 0
    Это не работает, мой массив URL-адресов по-прежнему пуст. Не уверен, что есть проблема с форматированием в реальном файле XML, который я пытаюсь открыть? Я очищаю файл .xml.gz, такой как тот, на который я ссылаюсь, и использую GzipFile, чтобы распаковать его.
  • 0
    Да, я думаю, что я отрубил некоторую важную информацию с помощью моего тестового файла, и добавление его в анализ должно помочь. Я обновил ответ.
2

Вы были близки к вашей попытке, но, как сказал mzjn в комментарии, вы не учитывали пространство имен по умолчанию (xmlns="http://www.sitemaps.org/schemas/sitemap/0.9").

Вот пример того, как учитывать пространство имен:

import xml.etree.ElementTree as ET
tree = ET.parse('my_local_filepath')

ns = {"sm": "http://www.sitemaps.org/schemas/sitemap/0.9"}

for elem in tree.findall(".//sm:loc", ns):
    print(elem.text)

выход:

https://www.bestbuy.com/
https://www.bestbuy.com/site/3d-printers/3d-printer-filament/pcmcat335400050008.c?id=pcmcat335400050008
https://www.bestbuy.com/site/3d-printers/3d-printing-accessories/pcmcat748300527647.c?id=pcmcat748300527647

Обратите внимание, что я использовал префикс пространства sm, но вы можете использовать любое NCName.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню