2015-08-14 83 views
0

我試圖解析rss-feed中的一些數據。這是它的外觀在xml文件中使用lxml的xpath中xpath的問題

<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:admin="http://webns.net/mvcb/"  xmlns:syn="http://purl.org/rss/1.0/modules/syndication/"> 
    <channel rdf:about="http://somelink.com"> 
     <!-- ordinary stuff goes here --> 
    </channel> 
    <item rdf:about="http://www.some/random/link/123"> 
     <title>title</title> 
     <link> 
     http://www.some/random/link/123 
     </link> 
     <description> 
      <![CDATA[ 
       ..description.. 
       ]]> 
     </description> 
     <dc:date>the date</dc:date> 
    </item> 
</rdf:RDF> 

現在,我想從RSS源,這是一個正常的飼料沒有問題,每項目元素的例子,但我似乎無法得到任何東西都來自這個。它只是返回一個空列表。

這是我使用的代碼:

from lxml import etree 
tree = etree.parse(url) 
items = tree.xpath("//item") 

是否有做的RDF:在開始RDF,或RDF:在每一個約= ....物品標籤?

以防萬一:
-The文件至少裝載監守etree.tostring(tree)沒有得到整個文件。
-I've嘗試使用nsmap = tree.getroot().nsmap(),但我不知道如果我這樣做是正確的
-On常規RSS提要的tree.getroot()收益率 - ><Element rss at 0x2fa4260>,但在這個文件中,它產生 - ><Element {http://www.w3.org/1999/02/22-rdf-syntax-ns#}RDF at 0x2fa4288>

回答

1

只要開始使用名稱空間(即使是空名稱空間前綴),您也必須在xpath中明確指出您正在討論的是什麼名稱空間。

爲此,lxml提供了一本字典,其中鍵是命名空間前綴(不管你喜歡)和值各自的命名空間(完全合格的名稱):

from lxml import etree 

xmlstr = """ 
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns="http://purl.org/rss/1.0/" 
    xmlns:dc="http://purl.org/dc/elements/1.1/" 
    xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" 
    xmlns:admin="http://webns.net/mvcb/" 
    xmlns:syn="http://purl.org/rss/1.0/modules/syndication/"> 
    <channel rdf:about="http://somelink.com"> 
     <!-- ordinary stuff goes here --> 
    </channel> 
    <item rdf:about="http://www.some/random/link/123"> 
     <title>title</title> 
     <link> 
     http://www.some/random/link/123 
     </link> 
     <description> 
      <![CDATA[ 
       ..description.. 
       ]]> 
     </description> 
     <dc:date>the date</dc:date> 
    </item> 
</rdf:RDF>""" 

xmldoc = etree.fromstring(xmlstr) 
nsmap = {"purl": "http://purl.org/rss/1.0/"} 
res = xmldoc.xpath("//purl:item", namespaces=nsmap) 
print res 

print "xml", etree.tostring(res[0]) 

運行這樣的代碼打印:

[<Element {http://purl.org/rss/1.0/}item at 0x7fc8fb20af80>] 
xml <item xmlns="http://purl.org/rss/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:admin="http://webns.net/mvcb/" xmlns:syn="http://purl.org/rss/1.0/modules/syndication/" rdf:about="http://www.some/random/link/123"> 
     <title>title</title> 
     <link> 
     http://www.some/random/link/123 
     </link> 
     <description> 

       ..description.. 

     </description> 
     <dc:date>the date</dc:date> 
    </item> 

教訓是:

  • 隨意忽略命名空間前綴在你的文件中,它們實際上是次要信息。請注意,XML允許在一個文檔中多次重複使用相同的名稱空間前綴,用於不同的完全限定名稱空間(可怕的想法,但是是true)。
  • 不要小心(理解不錯),你真正要使用的完全合格的命名空間。
  • 帶有名稱空間前綴和限定名稱的字典可能使用任何您喜歡的名稱空間前綴。它與源XML文件中的前綴無關。
+0

非常感謝!感謝您的好答覆,並且您的代碼像魅力一樣工作,儘管我不明白爲什麼某些事情已經完成,但我想我很快就會發現它。無論如何,我現在試圖迭代我發現的每個項目,我將如何從每個項目獲得標題/鏈接/等?普通的'item.find(「title」)'不起作用,'purl:item',nsmap'也不起作用。但再次感謝 – theusual

+0

沒關係,我設法弄清楚了。 'item.xpath(「./ purl:title」,namespaces = nsmap)',我錯過了意外的時間段(。)。 – theusual