Universal Feed Parser问题

时间:2014-03-05 08:51:07

标签: python xml rss feedparser

我正在使用python脚本来解析RSS链接。

我使用Universal Feed Parser我遇到了一些链接问题,例如在尝试解析FreeBSD Security Advisories时 以下是示例代码:

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

Feed [“items”]基本上应该返回Feed中的所有条目,即以item开头的字段,但它总是返回空。

我还可以确认按预期解析了以下链接:

这是Feed的问题,因为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 个答案:

答案 0 :(得分:1)

我发现问题出在于使用 namespace

for FreeBSD的RSS feed:

<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的feed中删除额外的名称空间声明时,一切都按预期工作。

那对你意味着什么?我可以想到几种不同的方法:

  1. 使用其他内容,例如BeautifulSoup。我试了一下它似乎有效。
  2. 下载整个RSS源,应用一些搜索/替换来修复命名空间,然后使用feedparser.parse()。这种方法很大;我不会自己用它。
  3. 更新

    以下是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
    ---
    ...
    

    注意:

    • 为了简洁起见,我省略了错误检查。
    • 我建议BeautifulSoup失败时仅使用feedparser API。原因是feedparser是正确的工具。希望他们能够更新它,以便将来更加宽容。