2012-02-23 13 views
5

Hialxml - trudności analizowania rss Stack Exchange Network karmić

Mam problemy parsowanie kanału RSS Stack Exchange Network w Pythonie. Kiedy próbuję uzyskać węzły podsumowujące, pusta lista jest zwracana

Próbowałem rozwiązać ten problem, ale nie mogę się obrócić.

Czy ktoś może pomóc? dzięki

In [3o]: import lxml.etree, urllib2

In [31]: url_cooking = 'http://cooking.stackexchange.com/feeds' 

In [32]: cooking_content = urllib2.urlopen(url_cooking) 

In [33]: cooking_parsed = lxml.etree.parse(cooking_content) 

In [34]: cooking_texts = cooking_parsed.xpath('.//feed/entry/summary') 

In [35]: cooking_texts 
Out[35]: [] 

Odpowiedz

9

Spójrz na tych dwóch wersjach

import lxml.html, lxml.etree 

url_cooking = 'http://cooking.stackexchange.com/feeds' 

#lxml.etree version 
data = lxml.etree.parse(url_cooking) 
summary_nodes = data.xpath('.//feed/entry/summary') 
print('Found ' + str(len(summary_nodes)) + ' summary nodes') 

#lxml.html version 
data = lxml.html.parse(url_cooking) 
summary_nodes = data.xpath('.//feed/entry/summary') 
print('Found ' + str(len(summary_nodes)) + ' summary nodes') 

Jak odkryto, druga wersja zwraca żadnych węzłów, ale wersja lxml.html działa dobrze. Wersja etree nie działa, ponieważ oczekuje przestrzeni nazw i działa wersja html, ponieważ ignoruje przestrzenie nazw. Po części w dół http://lxml.de/lxmlhtml.html, mówi: "Analizator składni HTML wyraźnie ignoruje przestrzenie nazw i niektóre inne XMLizmy."

Uwaga podczas drukowania węzła głównego wersji etree (print(data.getroot())) otrzymuje się coś w rodzaju <Element {http://www.w3.org/2005/Atom}feed at 0x22d1620>. Oznacza to, że jest to element kanału o przestrzeni nazw http://www.w3.org/2005/Atom. Oto poprawiona wersja kodu etree.

import lxml.html, lxml.etree 

url_cooking = 'http://cooking.stackexchange.com/feeds' 

ns = 'http://www.w3.org/2005/Atom' 
ns_map = {'ns': ns} 

data = lxml.etree.parse(url_cooking) 
summary_nodes = data.xpath('//ns:feed/ns:entry/ns:summary', namespaces=ns_map) 
print('Found ' + str(len(summary_nodes)) + ' summary nodes') 
+0

'data.xpath ('// ns: feed/NS: wejścia/ns: Podsumowanie', Przestrzenie nazw = { 'ns':„http: //www.w3.org/2005/Atom '}) ' – reclosedev

+0

gah, nic dziwnego! Wygląda na to, że api zmieniło w pewnym momencie nazwę słowa kluczowego 'namespaces'. Aktualizacja mojej próbki za pomocą działającego kodu. – gfortune

+0

dziękuję bardzo gfortune. Zacznę sprawdzać katalog główny, zanim przejdę do analizy. – MrCastro

6

Problem polega nazw.

Run to:

cooking_parsed.getroot().tag 

A zobaczysz, że element jest przestrzeni nazw jako

{http://www.w3.org/2005/Atom}feed 

Podobnie jeśli przejdź do jednego z zapisów paszowych.

Oznacza to, że prawo XPath w lxml jest:

print cooking_parsed.xpath(
    "//a:feed/a:entry", 
    namespaces={ 'a':'http://www.w3.org/2005/Atom' }) 
+0

Jakoś podejrzewam, że ta odpowiedź była dla ciebie łatwiejsza niż dla mnie. ;) Ohydnie przerywając twoją odpowiedź i możesz wskazać wszystkie błędy, które popełniłem w swoim. – gfortune