最近好几个地方需要用到爬虫,解决了一下并发的问题
学校的选课系统的课容量做不到实时更新,但是一天更新一次还是可以的.但是用node直接一个for循环就几十个几百个http请求易轻尘发出去了.顶多能成功1 2个,后面的就全都失败了.所以需要控制并发.
Async
Async是一个控制控制异步流程的库.可以控制异步函数执行的顺序.
from http://blog.fens.me/nodejs-async/
一句话概括,就是如果你想要循环执行异步代码,可以用async来控制异步执行流程.用maplimit甚至还可以控制并发.
之前想要把异步的第三方库同步化的时候找了一些方法,偶然看到了这个库,发现有些时候异步库同步化是不可能的,走偏路,应该直接异步处理.
var n = require('needle'); |
这是我用来抓学校选课系统的爬虫,学校系统比较简单,只需要不停地GET就能取到数据.这里是直接把爬回来的数据存到了文件里.
用到的http请求的库是needle
,之前没仔细去啃request
的文档的时候没找到怎么解决编码问题.学校的系统比较老,用的是gb2312
的编码.
map的使用方法是这样的
async.map(array,your_function,callback); |
array
中元素会分别传递给your_function
在your_function
中调用callback
,在array
中所有的元素都经过your_function
处理过之后,结果会拼接为一个数组传递给callback
比如说,
var async=require('async'); |
数组中的每一个元素分别传递给my_function
,然后调用callback,最后的结果会是
[2,4,6,8] |
相应的有一另外一个方法mapLimit(coll, limit, iteratee, [callback])
,其中limit可以设置最大同时进行的函数的数量.只要在这里设置一个比较小的数字,就可以控制并发了.(因为我们学校选课系统比较脆弱,我设置了3或者5)
递归
为了保证所有的课表都被爬一遍,如果是同步的话可以用循环来进行,但是这里是异步,我没想到怎么通过循环来进行,所以用了递归.