从下载说起

一、下载引擎

爬虫最基本的能力就是发起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做下载后的自定义处理。

results matching ""

    No results matching ""