2014-03-05 27 views
0

我正在研究一個python腳本來解析RSS鏈接。Universal Feed Parser問題

我用的是Universal Feed Parser,我有一些鏈接遇到的問題,例如在試圖解析FreeBSD Security Advisories 下面是示例代碼:

feed = feedparser.parse(url) 
    items = feed["items"] 

基本上進[「項目」]應該返回所有Feed中的條目,以item開始的字段,但始終返回空白。

我還可以確認爲預計以下鏈接解析:

這是一個與飼料問題,在FreeBSD中的那些做也不尊重標準?

編輯:

我使用Python 2.7。 我最終使用feedparser,與BeautifulSoup結合使用,如Hai Vu提議。 下面是示例代碼,我結束了,略有變化:

def rss_get_items_feedparser(self, webData): 
    feed = feedparser.parse(webData) 
    items = feed["items"] 
    return items 

def rss_get_items_beautifulSoup(self, webData): 
    soup = BeautifulSoup(webData) 
    for item_node in soup.find_all('item'): 
     item = {} 
     for subitem_node in item_node.findChildren(): 
      if subitem_node.name is not None: 
       item[str(subitem_node.name)] = str(subitem_node.contents[0]) 
     yield item 

def rss_get_items(self, webData): 
    items = self.rss_get_items_feedparser(webData) 
    if (len(items) > 0): 
     return items; 
    return self.rss_get_items_beautifulSoup(webData) 

def parse(self, url): 
     request = urllib2.Request(url) 
     response = urllib2.urlopen(request) 
     webData = response .read() 
     for item in self.rss_get_items(webData): 
      #parse items 

我也試過直接傳遞響應rss_get_items,沒有閱讀它,但它拋出和異常,BeautifulSoup嘗試當閱讀:

File "bs4/__init__.py", line 161, in __init__ 
    markup = markup.read() 
TypeError: 'NoneType' object is not callable   

回答

1

我發現問題是使用命名空間

對FreeBSD的RSS提要:

<rss xmlns:atom="http://www.w3.org/2005/Atom" 
    xmlns="http://www.w3.org/1999/xhtml" 
    version="2.0"> 

對於Ubuntu的飼料:

<rss xmlns:atom="http://www.w3.org/2005/Atom" 
    version="2.0"> 

當我從FreeBSD的飼料刪除多餘的命名空間聲明,一切正常。

那麼它對你意味着什麼?我可以想到幾種不同的方法:

  1. 使用別的東西,比如BeautifulSoup。我試過了,它似乎工作。
  2. 下載整個RSS源,應用一些搜索/替換來修復名稱空間,然後使用feedparser.parse()。這種方法是一個很大的破解。我不會自己使用它。

更新

這裏是rss_get_items()一個示例代碼這將返回您從一個RSS feed的項目清單。每個項目都是與一些標準鍵的字典,例如冠軍pubdate的鏈接,並GUID

from bs4 import BeautifulSoup 
import urllib2 

def rss_get_items(url):  
    request = urllib2.Request(url) 
    response = urllib2.urlopen(request) 
    soup = BeautifulSoup(response) 

    for item_node in soup.find_all('item'): 
     item = {} 
     for subitem_node in item_node.findChildren(): 
      key = subitem_node.name 
      value = subitem_node.text 
      item[key] = value 
     yield item 

if __name__ == '__main__': 
    url = 'http://www.freebsd.org/security/rss.xml' 
    for item in rss_get_items(url): 
     print item['title'] 
     print item['pubdate'] 
     print item['link'] 
     print item['guid'] 
     print '---' 

輸出:

FreeBSD-SA-14:04.bind 
Tue, 14 Jan 2014 00:00:00 PST 
http://security.FreeBSD.org/advisories/FreeBSD-SA-14:04.bind.asc 
http://security.FreeBSD.org/advisories/FreeBSD-SA-14:04.bind.asc 
--- 
FreeBSD-SA-14:03.openssl 
Tue, 14 Jan 2014 00:00:00 PST 
http://security.FreeBSD.org/advisories/FreeBSD-SA-14:03.openssl.asc 
http://security.FreeBSD.org/advisories/FreeBSD-SA-14:03.openssl.asc 
--- 
... 

注:

  • 我省略錯誤檢查爲簡潔起見。
  • feedparser失敗時,我建議只使用BeautifulSoup API。原因是feedparser是工作的正確工具。希望他們會在未來更新它以更加寬容。
+0

我得解析幾個RSS鏈接,你覺得BeautifulSoup能處理RSS的所有變種嗎?或者如果沒有結果使用BeautifulSoup,可以先使用feedparser嘗試使用組合。 – hDan

+0

我會和feedparser一起去,然後回到BeautifulSoup。 –