2016-11-02 4 views
1

Я делаю проект класса, где мне нужно сохранить список ссылок на текстовый файл.Анализ XML с помощью python и ElementTree

Я дал XML и пробовал перебирать все url's, но проблемы.

Я пробовал использовать дерево элементов, но не могу перебирать через я прочитал много других вопросов и пробовал это без успеха. Пожалуйста, помогите

Структура как этот

<urlset xmlns="http://www.crawlingcourse.com/sitemap/1.3"> 
    <url> 
    <loc> 
     http://www.crawlingcourse.com/item-3911512 
    </loc> 
    </url> 
<url>.... 
+1

Как выглядит ваш код до сих пор? Каким образом это не работает? – larsks

+0

Из примера просто нужно убедиться, что ваш XML правильный (все элементы закрыты, doctype и т. Д.)? – Eugene

ответ

4

Я предлагаю вам использовать lxml эффективно анализировать файл XML.

from lxml import etree 

Ваш образец XML не очень хорошо образован, я исправил это так:

content = """\ 
<urlset xmlns="http://www.crawlingcourse.com/sitemap/1.3"> 
    <url> 
    <loc> 
     http://www.crawlingcourse.com/item-3911512 
    </loc> 
    </url> 
</urlset>""" 

Чтобы разобрать файл, вы можете использовать etree.parse(). Но так как этот образец является строка, я использую etree.XML():

tree = etree.XML(content) 

естественный путь для поиска элементов в дереве XML использует XPath. Например, вы можете сделать это:

loc_list = tree.xpath("//url/loc") 

Но вы не получите ничего:

for loc in loc_list: 
    print(loc.text) 
# None 

причины, об этом, это, вероятно, ваша проблема, в том, что <urlset> использовать пространство имен по умолчанию: «http://www.crawlingcourse.com/sitemap/1.3» ,

Чтобы сделать его работу, вам необходимо использовать функцию xpath() с этим пространством имен. Давайте дадим имя этого пространства имен: «S»:

NS = {'s': "http://www.crawlingcourse.com/sitemap/1.3"} 

Затем используйте префикс s в этом выражении XPath, как это:

loc_list = tree.xpath("//s:url/s:loc", namespaces=NS) 

for loc in loc_list: 
    print(loc.text) 
#  http://www.crawlingcourse.com/item-3911512 

Поскольку ваш XML отступом, необходимо обирать пробелы:

for loc in loc_list: 
    url = loc.text.strip() 
    print(url) 
# http://www.crawlingcourse.com/item-3911512 
+0

Спасибо @ Laurent за то, что нашли время, чтобы объяснить. Вы решили мою проблему и научили меня, как она работает. Спасибо – hahu

1

Ну, проблема в том, что это пространство имен.

Вот рабочий код:

from xml.etree.cElementTree import XML, fromstring, tostring, ElementTree 
xml_string = '<?xml version="1.0"?><urlset><url><loc>http://www.crawlingcourse.com/item-3911512</loc></url></urlset>' 
tree = ElementTree(fromstring(xml_string)) 
print [elem.text for elem in tree.iter(tag='loc')] 

Теперь, если вы хотите добавить <urlset xmlns="http://www.crawlingcourse.com/sitemap/1.3">, теги будут отличаться. От http://www.w3schools.com/xml/xml_namespaces.asp:

Пространства имен XML - Атрибут xmlns. При использовании префиксов в XML необходимо определить пространство имен для префикса. Пространство имен может быть определено атрибутом xmlns в начальном теге элемента. Объявление пространства имен имеет следующий синтаксис. XMLNS: префикс = "URI".

Отбросил меня тоже!

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