关于pubsubhubbub和Google Reader

上一篇文章中,我描述了自己如何重制了一个Danbooru的feed。然而,经过一夜的睡眠,我「惊喜」地发现Google Reader在睡前到醒后的7个多小时里面都没有抓取过我订阅了的这个feed——也就是说,就算重制的feed包含10000条最近更新,只要GR不主动抓取,那这些更新也还是没有意义。

绝望之下,觉得归根到底还是弄清楚pubsubhubbub(以下简称PuSH)协议的原理。试着搜索有关GR和PuSH的文章,发现@keakon曾经发表过『PubSubHubbub不通知Google Reader的原因』『实现PubSubHubbub订阅』和『使用PubSubHubbub』三篇文章。拜读之后,明白了什么叫publisher和subscriber,也得知GR可能会自动忽略订阅数少的feed的PuSH,于是先写了一个sub,然后拿菜包工作室来当小白鼠(不好意思啦@tc201158),由于这个博客刚开张,只有我一个人在GR订阅了(订阅数为1),在装了PuSH插件并在hub上进行subscribe之后果然还是无法实现PuSH,可是我用另外一个GR帐号订阅其feed(订阅数为2)之后,PuSH就能正常工作了。

大喜,以为终于找到了原因,于是对重制的feed也如此这般地弄,结果却失败了…无奈之下,我又试着对danbooru的原feed重新在hub上subscribe,发现原feed实现了PuSH的同时,重制的feed也实现了PuSH!难道因为重制的feed中提供的id、url等信息仍然是原feed的信息,所以只有在收到原feed更新的ping请求后,hub才会通知GR抓取重制的feed?

不过既然原feed能够实现PuSH,那重制的feed就没什么意义了;只需要实现在GAE上利用cron定期检查原feed是否有更新,有的话就ping一下hub就可以了。于是又浪费了一整天的人参来实现了这个功能…

至此,对Danbooru feed的PuSH改造完满完成。经验教训:

  1. 尽管有约定,但在feed中添加hub link并不是必须的,至少对于Google的hub(http://pubsubhubbub.appspot.com)是如此;
  2. 利用第一点,可以对任何一个feed实现PuSH改造。先写一个sub以便在Google的hub上对feed进行订阅(必须有订阅才能实现PuSH),然后写一个cron定期检查feed的更新并且ping hub即可;
  3. 开发GAE应用时,利用handlers和wsgi来架构整个应用,无论是应用结构还是debug都方便太多了,决定从此放弃像twitter2weiboviagtalk那样面向过程开发的方法…

题外话。今天是⑨月⑨日的⑨节,可是⑨的同人图一点都不给力啊…

重制danbooru的feed

作为一只东方众,我每天都会通过Danbooru来收一堆东方同人图——Danbooru类型的图站有一个很出色的地方,就是搜索结果可以输出rss feed,直接在GR中添加feed「http://danbooru.donmai.us/post/atom?tags=touhou」,就可以在GR中订阅D站的带有touhou标签的新投稿,十分方便。

前两天开始,我发现这个feed的更新数变少了——通常一天下来会有超过100的更新,但当天只有六十多,而且某次我在扫feed时,发现feed的上一次抓取时间是2个小时以前;而另外一次扫feed时,发现feed一下子实时更新了20篇——通常一个rss feed只会包含最近20篇投稿,这意味着由于GR的抓取频率比较慢,很可能没有办法将所有的近期更新抓全。

为了解决这个问题,我首先想到的是PubHubSubBub——一个能够在feed有更新时主动通知Hub(如GR),使其主动过来抓取更新的协议。我当然不可能直接让D站方面实现这个协议,但搜索了一下相关资料,似乎并没有要求通知者和feed一定要同一服务器,所以利用PubHubSubBub的代码在本机上测试了一下,发现即使通知了http://pubhubsubbub.appspot.com/,GR也不会主动抓取对应地址的更新…几番测试下依然无解,只能放弃了这个想法,转而考虑为D站的feed制作一个包含足够多篇数的近期更新的feed。

重制feed的应用仍然放在GAE上。初步构想了一下,应用要实现2个功能:

  1. 以比GR高得多的抓取频率(如1分钟1次)抓取D站的对应feed,并且将新投稿保存在数据库中;
  2. 输出rss feed,其中包含足够覆盖GR抓取频率的数量的新投稿数,甚至可以根据GR抓取的User-Agent智能判断那些投稿已经被GR抓取。

然后开始忙活…为了解析D站的feed,先是打算用minidom,后来发现Google Data APIs中提供了atom的解析器,于是将代码下载下来,稍微看了下doc就知道怎样用了;输出rss时则参考了PubHubSubBub代码中的Atom模板。

由于不懂如何在本地环境调试GAE应用,所以每次都要先上传到远程再调试;由于GAE的log有延迟,所以程序出错后要等几分钟才能在后台看到trackback,后来干脆直接把整个程序代码放到一个try-except块中,再用print命令把异常打印到网页上。

就这么个小东西弄了一天,半吊子的悲剧啊…

架设个人DNS服务器来解决一些「国情」问题@

 

具体请移步这里:http://www.blogjava.net/stone2083/archive/2011/07/09/353664.html

这个小程序的本意是在局域网中建立一个简单的DNS服务器,不过由于其支持通配符hosts,所以可以用于干坏事:之前的hosts经常要这样改:

203.208.46.133 www.google.com
203.208.46.133 mail.google.com

有了这个应用,就可以实现这样的hosts:

203.208.46.133 *.google.com
203.208.46.133 *.youtube.com

该作者刚更新了一个standalone版本序,配置十分方便,推荐有大规模hosts需要的童鞋去试试看。