最近在考虑用appengine抓取豆瓣小组帖子的问题,这里整理一下思路。

如果帖子不长可以考虑在一个请求内抓完,但是豆瓣上有趣的帖子基本都有分页,而且还要对帖子进行脱水处理,如果在一个请求内抓的话要么会超时要么会出那个循环过多的异常。所以考虑用appengine的Taskqueue来跟据分页建立任务列队抓取,每个分页的Url正好对应一个Task Queue。

首先由用户提交小组topic首页的url,然后直接抓取首页上的作者、标题、发布时间、作者url、帖子url,帖子当前页码等相关信息,用帖子id加特定字符合成key_name保存topic数据到数据库。

下一步就是建立请求的任务列表,从数据库里调出帖子当前页码的数据,然后批量生成任务,appengine文档里据说是提到超过5个Task就不能用run_in_transaction了,而且还不能用自定义的name,不过我用自定义的name能添加上。

其他页面需要抓的内容,需要用前面保存过的topic的作者名字或者作者url判断来进行脱水,需要保存的内容包括,发布时间、内容,也可以考虑保存一下楼层可用来生成key_name。

还有个问题是就是如何处理用户重复提交的url。用户提交url以后,首先按照url生成key_name然后到数据库里检索,如果不存在的话,直接到第一步,如果已经存在的话就比较当前抓取的页码数量和数据库中存储的数量是否相等,如果相等则生成一个抓最后一个页面的任务,如果不相等的话从相等页面一直抓到当前页面。

用urlfetch毕竟性能有限,主要就是BeautifulSoup性能还不是很理想,用lxml的话gae不支持,用正则解析html表达式不好写。如果豆瓣的小组能有api的话也就没这个问题了。