2012-02-23 11 views
5

ヒアlxml - 難読化スタックエクスチェンジrssフィード

私はpythonのstackexchangeからのrssフィードの解析に問題があります。 サマリーノードを取得しようとすると、空のリストが返されます

私はこれを解決しようとしていますが、私の周りを取り巻くことはできません。

誰でも手助けできますか? おかげ

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]: [] 

答えて

9

は、これら2つのバージョン

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') 

を見てみましょう、2番目のバージョンではノードが返されませんが、lxml.htmlバージョンが正常に動作します。 etreeバージョンは、名前空間を期待しているため動作していません。htmlバージョンは、名前空間を無視するため動作しています。途中でhttp://lxml.de/lxmlhtml.htmlと書かれているように、「HTMLパーサーは名前空間やその他のXMLismを無視している」

注意etreeバージョン(print(data.getroot()))のルートノードを印刷すると、<Element {http://www.w3.org/2005/Atom}feed at 0x22d1620>のようなものが得られます。つまり、名前空間がhttp://www.w3.org/2005/Atomのフィード要素です。ここに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:フィード/ NS:エントリ/ NS:要約'、ネームスペース= { 'NS':「のhttp: //www.w3.org/2005/Atom '}) ' – reclosedev

+0

ガー、不思議ではない! apiがある時点で 'namespaces'キーワードの名前を変更したように見えます。サンプルを作業コードで更新しています。 – gfortune

+0

ありがとうございます。私はそれを解析する前にルートをチェックし始めるでしょう。 – MrCastro

1

beautifulsoupインポートからBeautifulStoneSoupを使用してみてください。 トリックを行う可能性があります。あなたが発見したよう

6

問題は名前空間です。

を実行し、これは:

cooking_parsed.getroot().tag 

そして、あなたは、あなたがフィードエントリの1つに移動した場合の要素は同様

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

として名前空間されていることがわかります。

これはlxmlの中右XPathがあることを意味する:

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

どういうわけか私はこの答えがあなたのために簡単だったと私は思っていました。 ;)あなたの答えを丁寧にぶつけて、私が私の中で作った間違いを指摘してください。 – gfortune