2015-07-07 2 views
0

У меня есть карта сайта, как это: http://www.site.co.uk/sitemap.xml, которое структурировано так:Анализировать XML Sitemap с Python

<sitemapindex> 
    <sitemap> 
    <loc> 
    http://www.site.co.uk/drag_it/dragitsitemap_static_0.xml 
    </loc> 
    <lastmod>2015-07-07</lastmod> 
    </sitemap> 
    <sitemap> 
    <loc> 
    http://www.site.co.uk/drag_it/dragitsitemap_alpha_0.xml 
    </loc> 
    <lastmod>2015-07-07</lastmod> 
    </sitemap> 
... 

И я хочу, чтобы извлечь из него данные. Прежде всего, мне нужно подсчитать, сколько <sitemap> находится в xml, а затем для каждого из них, извлечь данные <loc> и <lastmod>. Есть ли простой способ сделать это в Python?

Я видел другие вопросы, подобные этому, но все они извлекают, например, каждый элемент <loc> внутри xml, мне нужно извлекать данные отдельно от каждого элемента.

Я пытался использовать lxml с этим кодом:

import urllib2 
from lxml import etree 

u = urllib2.urlopen('http://www.site.co.uk/sitemap.xml') 
doc = etree.parse(u) 

element_list = doc.findall('sitemap') 

for element in element_list: 
    url = store.findtext('loc') 
    print url 

но element_list пуста.

+2

Используйте 'lxml' библиотеку. –

+0

Хороший вопрос в StackOverflow показывает, что вы уже пробовали, и как он терпит неудачу. (Я полностью согласен с Анандом в том, что 'lxml' является правильным инструментом для работы, если вы попробуете его и у вас возникнут проблемы *, то * у вас возникнет вопрос задать здесь вопрос). –

+0

Можно также использовать https://docs.python.org/2/library/xml.etree.elementtree.html, нет? – tandy

ответ

4

Я решил использовать библиотеки Requests и BeautifulSoup. Я создал словарь, где ключ - это url, а значение - последняя измененная дата.

from bs4 import BeautifulSoup 
import requests 

xmlDict = {} 

r = requests.get("http://www.site.co.uk/sitemap.xml") 
xml = r.text 

soup = BeautifulSoup(xml) 
sitemapTags = soup.find_all("sitemap") 

print "The number of sitemaps are {0}".format(len(sitemapTags)) 

for sitemap in sitemapTags: 
    xmlDict[sitemap.findNext("loc").text] = sitemap.findNext("lastmod").text 

print xmlDict 

Или с lxml:

from lxml import etree 
import requests 

xmlDict = {} 

r = requests.get("http://www.site.co.uk/sitemap.xml") 
root = etree.fromstring(r.content) 
print "The number of sitemap tags are {0}".format(len(root)) 
for sitemap in root: 
    children = sitemap.getchildren() 
    xmlDict[children[0].text] = children[1].text 
print xmlDict 
+0

HTML-парсер для XML? Я имею в виду, это работает, но это будет бесполезно разрешительным. –

+0

@CharlesDuffy Обновлен мой ответ ... Я никогда не использовал lxml раньше, так что мне это немного понравилось – heinst

+0

BeautifulSoup говорит, что поскольку он не указан, он использует lxml-парсер по умолчанию, а затем меняет 'soup = BeautifulSoup (xml)' to 'soup = BeautifulSoup (xml, 'lxml') 'работает отлично! – Hyperion

0

Здесь с помощью BeautifulSoup получить sitemap счет и извлекать текст:

from bs4 import BeautifulSoup as bs 

html = """ 
<sitemap> 
    <loc> 
    http://www.site.co.uk/drag_it/dragitsitemap_static_0.xml 
    </loc> 
    <lastmod>2015-07-07</lastmod> 
    </sitemap> 
    <sitemap> 
    <loc> 
    http://www.site.co.uk/drag_it/dragitsitemap_alpha_0.xml 
    </loc> 
    <lastmod>2015-07-07</lastmod> 
    </sitemap> 
""" 

soup = bs(html, "html.parser") 
sitemap_count = len(soup.find_all('sitemap')) 
print("sitemap count: %d" % sitemap) 
print(soup.get_text()) 

Выход:

sitemap count: 2 

    http://www.site.co.uk/drag_it/dragitsitemap_static_0.xml 

2015-07-07 

    http://www.site.co.uk/drag_it/dragitsitemap_alpha_0.xml 

2015-07-07 
Смежные вопросы