Python Feedparser:如何检查新的RSS数据?

21 投票
2 回答
13646 浏览
提问于 2025-04-17 21:01

我正在使用feedparser这个Python库来不断获取RSS数据。我写的代码可以让我请求一次RSS数据。现在我的代码是这样的:

import feedparser

rssPR = feedparser.parse('http://www.prnewswire.co.uk/rss/consumer-technology/wireless-      communications-news.rss')
rssDataList = []

for index, item in enumerate(rssPR.entries):
    rssDataList.append([item.published.encode('utf-8'), item.title.encode('utf-8')])

print rssDataList[0]  #for debugging purposes
print rssPR.modified #for testing purposes
  1. 我可以在代码中添加什么,让它只在RSS被修改时才检查新的RSS数据呢?

  2. 假设我有一个包含10个RSS项目的列表,而RSS源更新了2个新的RSS项目。我该怎么做才能只把这2个新项目添加到我创建的rssDataList中?我不想一直把相同的RSS添加到我的数据库里。

相关问题:

2 个回答

0

其实有很多种方法可以解决这个问题。在我看来,最简单的方法之一就是为最新的记录生成一个独特的“哈希值”。比如说:

import hashlib
import feedparser

rssPR = feedparser.parse('http://www.prnewswire.co.uk/rss/consumer-technology/wireless-communications-news.rss')
rssDataList = []

# Generate MD5 hash of the most current item's title and link elements.
lasthash = hashlib.md5(rssPR.entries[0].link + rssPR.entries[0].title).hexdigest()

for index, item in enumerate(rssPR.entries):
    rssDataList.append([item.published.encode('utf-8'), item.title.encode('utf-8')])

print rssPR.modified # Thu, 06 Mar 2014 00:13:50 GMT
print lasthash # 4167402f1ba2629fcc71003121aa1d25

然后如果你这样做:

rssCheck = feedparser.parse('http://www.prnewswire.co.uk/rss/consumer-technology/wireless-communications-news.rss')
thishash = hashlib.md5(rssCheck.entries[0].link + rssCheck.entries[0].title).hexdigest()

lasthash == thishash
>> True # up to date

这样一来,每次你再次检查信息流的时候,如果哈希值不同,就说明内容已经更新了。这样就省去了比较时间和日期的麻烦。

33

关于只有在信息源发生变化时才下载的情况,你可以使用HTTP头部中的ETag,如果不行的话,还可以用Last-Modified作为备用。

>>> feed.etag
'"6c132-941-ad7e3080"'
>>> feed.modified
'Fri, 11 Jun 2012 23:00:34 GMT'

你可以在调用feedparser.parse时指定这些信息。如果这些信息没有变化,服务器会返回状态码304(未修改)。

简单来说,就是这个例子:

import feedparser
url = 'http://feedparser.org/docs/examples/atom10.xml'

# first request
feed = feedparser.parse(url)

# store the etag and modified
last_etag = feed.etag
last_modified = feed.modified

# check if new version exists
feed_update = feedparser.parse(url, etag=last_etag, modified=last_modified)

if feed_update.status == 304:
    # no changes

注意:你需要检查feed.etagfeed.modified是否存在。

feedparser库会自动发送If-None-Match头部,里面包含你提供的etag参数,同时也会发送If-Modified-Since头部,里面包含modified的值。

来源:Feedparser关于http和etag的文档



 


为了澄清评论中提到的问题:
这需要服务器支持这两个头部中的任意一个。

如果这两个头部都不管用,你就不能使用这个方法,只能每次都从服务器下载信息源,即使它没有变化,因为你在下载之前根本无法判断。

这意味着你每次都得下载信息源,并记录你已经看过的条目。
如果你想避免显示已经看过的内容(例如,只打印新的条目),你必须保持一个已看过信息源的列表。有些信息源会为每个entry提供一个id字段,你可以用它来处理这种情况。否则,你需要稍微动动脑筋,找出对于你的信息源来说,什么样的条目是相同的。

撰写回答