WebDigger爬虫

WebDigger是一个采用Java开发的爬虫框架。WebDigger的目标是简化爬虫的开发流程,让开发者只用关心抓取页面的数据提取和数据保存的逻辑。WebDigger也提供注解的方式来配置要抓取的网页数据,以减少代码的开发。项目地址

组件

  • Digger
    负责控制数据流在系统中所有组件中流动,并在相应动作发生时触发事件。

  • Scheduler
    调度器从引擎接受request并将他们入队,以便之后引擎请求他们时提供给引擎。

  • Downloader
    下载器负责获取页面数据Response,供Processor模块进行数据提取

  • Processor
    是用于分析response并提取item(需要的抓取的具体的数据)。每个spider的Processor负责处理一个特定(或一些)网站。网页数据提取支持Jsoup和Xpath的方式。

  • Storage
    负责处理被Processor提取出来的item。主要是用来将item进行持久化操作(保存到文件,打印输出等)。

下面是一个抓取豆瓣图书的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class DBBookSpider extends Spider {

/**
* 自定义的processor,负责解析页面书籍的相关信息
*/

@Override
public void process(Response response) {
Selector selector = response.getJXDoc().getSelector();

Map<String, String> fieldMap = new HashMap<String, String>();
fieldMap.put("name", "div.info > h2 > a");
fieldMap.put("pub", "div.info > div.pub");
fieldMap.put("score", "div.info > div.star.clearfix > span.rating_nums");
fieldMap.put("comments", "div.info > div.star.clearfix > span.pl");
fieldMap.put("intro", "div.info > p");

List<Map<String, String>> list = selector.foreach("#subject_list > ul > li", fieldMap);

response.put("list", list);
}

/**
* 自定义的Storage,这里仅仅是将信息打印输出
*/

@Override
public void persist(Item item) {
List<Map<String, String>> list = (List<Map<String, String>>) item.get("list");
if (list != null && !list.isEmpty()) {
for (Map<String, String> map: list) {
System.out.println(JSON.toJSONString(map));
}
}

}

public static void main(String[] args) {
new DBBookSpider()
.addStartUrls("https://book.douban.com/tag/中国文学",
"https://book.douban.com/tag/中国文学?start=20&type=T",
"https://book.douban.com/tag/中国文学?start=40&type=T").setFollowed(false).start(); // 启动爬虫
}
}

基于注解方式的抓取数据的定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static class QQTechModel extends CrawlerModel {

@FieldRule(type = FieldType.CSS, expr = "#C-Main-Article-QQ > div.hd > h1")
private String title;

@FieldRule(type = FieldType.CSS, expr = "#C-Main-Article-QQ > div.hd > div > div > span.pubTime")
private String pubTime;

@FieldRule(type = FieldType.CSS, expr = "#Cnt-Main-Article-QQ")
private String content;

// ... get & set

}

项目地址

ps: 欢迎有兴趣的同学,一起沟通学习~