布丁的博客

好吃的技术宅∧ ∧

NthsKeys – 简单的爬虫

| 0 comments

这是一个简单的小爬虫~

为了得到最新的压缩包,我们需要定时爬取学校网站文章列表。一旦有符合条件的新文章出现,就下载内含的附件,并记录在数据库中。

首先要做的是发请求得到 HTML 文本。分析请求可以发现,要得到文章列表(“教学频道”)某一页的内容,需要给列表网站发送一个 POST 请求,内容形如 currentPage=3  。整个过程只需要发送一次 POST 请求,因此原地封装一个 Promise 对象即可,无需再做抽象。

这样就能得到列表网页的内容。考虑到网页并不大,这里我们把 HTTP 响应在内存里累积起来,一次性返回。

多亏了 cheerio 这款衍生自 jQuery 的 DOM 操作库,我们可以用类似 CSS 选择器的方式选取所需的元素,这里就是所有文章对应的标题、链接和时间信息。

接下来过滤出标题中含有关键字“暑假作业”,并且发表时间较新的文章进行操作,依葫芦画瓢就行,很容易获取压缩包的链接。下载压缩包的过程我们也把它封装成 Promise 对象:

这里我们打开了两个流,一个用来写入文件,一个从 HTTP 响应中读取字节。因为压缩包有可能相当大,在内存里直接累积并不是一个明智的选择。幸好 Node 为我们封装了 pipe 函数,它可以方便地把读流(exm?)和写入流“连通”起来。实际上,Node 底层开辟了一小块缓冲区,每次从读流读入一定字节填充进去并使读流暂停流动,然后把缓冲区内容流入写入流,完成后再恢复读流流动,周而复始,直到读流“枯竭”,关闭双方流。有了这个函数,我们可以放心地把 HTTP 回应流流向文件流。

接下来就可以入库了,详情请参考前一篇。最后整个模块导出一个完整的 Promise 对象,调用方传入参数,接一个 then  即可。

这个小爬虫的核心在于网络请求的处理,以及 DOM 解析,并没有反反爬虫之类的麻烦事。接下来就该等待用户解压了……


2016-08-04 更新:

学校官网文章标题的格式千奇百怪,之前没考虑到,漏了一个高一的。解决方案是不停往元素内部挖,直到挖进文本节点即可。
前几天学校官网挂了一阵子,爬虫异常处理不到位,导致整个网站也跟着挂了。现在已修复。详见这个 commit

一个压缩包挺大的,有的上百兆。而 Travis CI 的运行环境在国外,下载压缩包特别慢,导致系统以为我故意拖延,真是尴尬…我的处理方法是下载进行一分钟就输出一点,这样 Travis CI 不会抱怨了吧。详见这个 commit

anyShare分享到:

发表评论

Required fields are marked *.