官网地址:https://github.com/CrawlScript/WebCollector
WebCollector的Http请求结果有两种状态:请求成功和请求失败。这两种状态的定义如下:
WebCollector默认使用OkHttpRequester作为Http请求插件(Requester插件)。可以通过下面的代码查看OkHttpRequester认为请求成功地状态码集合:
public static void main(String[] args) {
OkHttpRequester requester = new OkHttpRequester();
System.out.println(requester.getSuccessCodeSet());
}
执行结果如下,可以看到,OkHttpRequester默认会将404、200、301、302都认为是访问成功:
[404, 200, 301, 302]
这里要注意,OkHttpRequester在遇到301和302时并不会自动跳转,也不建议在Http请求插件中定制自动跳转功能。建议在visit中处理,处理跳转方法如下:
@Override
public void visit(Page page, CrawlDatums next) {
// 如果遇到301或者302,手动跳转(将任务加到next中)
// 并且复制任务的meta
if(page.code() == 301 || page.code() == 302){
next.addAndReturn(page.location()).meta(page.meta());
return;
}
}
上面的处理方法利用page.location()方法获取Http头中的Location头(重定向URL),并将其作为一个新的任务加到next中。任务的meta(附加信息)也需要被复制到新的任务中。之所以这样设计,是因为很多采用自动跳转的爬虫框架会导致重复的采集,例如访问http://a.com和http://b.com都会重定向到http://c.com,对于一些采用自动去重机制的框架,可能会有如下的采集流程。在下面的流程中,http://c.com页面上的数据被重复采集了。
错误的重定向处理方式:
1. 检查http://a.com是否被访问,发现未被访问
2. 访问http://a.com,自动重定向到http://c.com,获取数据,记录http://a.com已被采集(注意这里可能不会记录http://c.com被访问)
3. 检查http://b.com是否被访问,发现未被访问
4. 访问http://b.com,自动重定向到http://c.com,获取数据,记录http://b.com已被采集(注意这里可能不会记录http://c.com被访问)
但是如果按照上面推荐的方法,即不在Requester中自动跳转,而是在visit中处理重定向,就不会出现这个问题。虽然爬虫会向next(后续任务)中添加两次http://c.com,但是爬虫是有自动去重机制的,重复的任务是会被去重的。最核心的原因是,如果不在Requester插件中自动进行跳转,一个URL可以与服务器上的响应一一对应,而不会出现上面错误的方法中,两个URL对应同一个响应(经过自动重定向,响应都是http://c.com)。
对于一些特殊的情况,我们需要将301或者302设置为请求失败,例如采集搜狗微信时,301或302可能是你出发了反爬虫验证码,会重定向到验证码页面,这种情况需要将其认为是请求失败,通过重新请求(可能使用新的代理)来获得正确地响应,可以通过下面的代码将301和302设置为请求失败:
public static void main(String[] args) {
OkHttpRequester requester = new OkHttpRequester();
requester.removeSuccessCode(301);
requester.removeSuccessCode(302);
System.out.println(requester.getSuccessCodeSet());
}
运行结果如下,可以看到成功状态码列表中已经没有了301和302:
[404, 200]
如果希望将一些Http状态码设置为请求成功(如304),可以通过下面的代码:
public static void main(String[] args) {
OkHttpRequester requester = new OkHttpRequester();
requester.addSuccessCode(304);
System.out.println(requester.getSuccessCodeSet());
}
运行结果如下:
[304, 404, 200, 301, 302]