从下载说起
一、下载引擎
爬虫最基本的能力就是发起http请求,下载网页,gecco默认采用httpclient4作为下载引擎。通过实现Downloader接口可以自定义自己的下载引擎,在启动GeccoEngine时需要设置自己的下载引擎
@Gecco(matchUrl="https://github.com/{user}/{project}", pipelines="consolePipeline", downloader="htmlUnitDownloder")
二、HttpRequest和HttpResponse
HttpRequest表示下载请求,HttpResponse表示下载响应。爬虫下载网页都会模拟浏览器包装成GET或者POST请求,HttpGetRequest和HttpPostRequest分别对应GET和POST请求。
- gecco的请求支持模拟userAgent,并且支持userAgent的随机轮询,在calsspath的根目录下定义userAgents文件,每行表示一个UserAgent;
- gecco支持cookie定义,request.addCookie(),可以模拟用户登录;
- gecco支持代理服务器的随机轮询,在classpath的根目录下定义proxys文件,每行表示一个代理服务器的主机和端口,如127.0.0.1:8888;
三、下载地址管理
通常爬虫需要一个有效管理下载地址的角色,Scheduler负责下载地址的管理。gecco对初始地址的管理使用StartScheduler,StartScheduler内部采用一个阻塞的FIFO的队列。初始地址通常会派生出很多其他待抓取的地址,派生出来的其他地址采用SpiderScheduler进行管理,SpiderScheduler内部采用线程安全的非阻塞FIFO队列。这种设计使的gecco对初始地址采用了深度遍历的策略,即一个线程抓取完一个初始地址后才会去抓取另外一个初始地址;对初始地址派生出来的地址,采用广度优先策略,派生地址的获取会在下面详细说明。另外,gecco的分布式抓取也是通过Scheduler来完成了,准确的说是通过实现不同的StartScheduler来将初始地址分配到不同的服务器中来完成的。gecco的分布式抓取默认采用redis来实现,具体可以参考gecco-redis项目。
GeccoEngine.create().scheduler(new RedisStartScheduler("127.0.0.1:6379"))
四、初始地址和派生地址
爬虫通常会从若干个初始地址开始爬取网页,爬取下来的网页可能包含其他需要继续抓取的页面,典型的例子是列表页和详情页。列表页作为初始地址,抓取完成后需要针对每个列表项再抓取对应的详情页。gecco派生地址的方式有两种:一种是通过注解@Href(click=true),click为true时,抽取出来的url会继续抓取,如:
@Href(click=true)
@HtmlField(cssPath=".tm-qx-nrBox a")
private String detailUrl;
还一种是显式的加入SpiderScheduler的方法,如:
SchedulerContext.into(currRequest.subRequest("subUrl");
使用@Request注解可以获得当前HttpRequest对象,使用当前request的subRequest方法生成派生地址的请求,这样在相应的pipeline类中即可控制派生请求的增加。
五、多个初始地址的配置
通过在classpath的根目录下放置配置文件starts.json可以配置多个初始地址,如下:
[
{
"charset": "GBK",
"url": "http://item.jd.com/1455427.html"
},
{
"url": "https://github.com/xtuhcy/gecco"
}
]
六、BeforeDownload和AfterDownload
一些特殊的场景,可能会需要在下载前做下载的预处理和在下载后做特定的处理,之后再传递给pipeline进行处理,这时需要实现BeforeDownload和AfterDownload。如:
@GeccoClass(CruiseDetail.class)
public class CruiseDetailBeforeDownload implements BeforeDownload {
@Override
public void process(HttpRequest request) {
}
}
上面的类针对CruiseDetail这个bean的下载前会做自定义的处理。
@GeccoClass(CruiseRedirect.class)
public class CruiseRedirectAfterDownload implements AfterDownload {
@Override
public void process(HttpRequest request, HttpResponse response) {
}
}
上面这个类会对CruiseRedirect这个bean做下载后的自定义处理。