WebMagic学习(一)之Hello world
Java爬虫项目简介
大型的:
Nutch apache/nutch · GitHub
apache下的开源爬虫程序,功能丰富,文档完整。有数据抓取解析以及存储的模块。适合做搜索引擎,分布式爬虫是其中一个功能。
Heritrix internetarchive/heritrix3 · GitHub
比较成熟的爬虫。经历过很多次更新,使用的人比较多,功能齐全,文档完整,网上的资料也多。有自己的web管理控制台,包含了一个HTTP 服务器。操作者可以通过选择Crawler命令来操作控制台。
小型的:
Crawler4j yasserg/crawler4j · GitHub
因为只拥有爬虫的核心功能,所以上手极为简单,几分钟就可以写一个多线程爬虫程序
WebCollector CrawlScript/WebCollector · GitHub(国人作品)
目标是在让你在5分钟之内写好一个爬虫。参考了crawler4j,如果经常需要写爬虫,需要写很多爬虫,还是不错的,因为上手肯定不止5分钟。缺点是它的定制性不强。
WebMagic code4craft/webmagic · GitHub(国人作品,推荐)
垂直、全栈式、模块化爬虫。更加适合抓取特定领域的信息。它包含了下载、调度、持久化、处理页面等模块。每一个模块你都可以自己去实现,也可以选择它已经帮你实现好的方案。这就有了很强的定制性。
WebMagic初探
WebMagic的结构分为Downloader、PageProcessor、Scheduler、Pipeline四大组件,并由Spider将它们彼此组织起来。更多信息可见 http://webmagic.io/docs
WebMagic第一个爬虫项目
爬取干货集中营的历史数据为例子:
- 使用maven来构建项目,pom配置
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-core</artifactId>
<version>0.6.1</version>
</dependency>
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-extension</artifactId>
<version>0.6.1</version>
</dependency>
代码如下:
package com.sima.crawler;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.pipeline.ConsolePipeline;
import us.codecraft.webmagic.processor.PageProcessor;
/**
* Created by maple on 2017-04-28.
*/
public class GankRepoPageProcessor implements PageProcessor {
//抓取网站的相关配置,包括编码、抓取间隔、重试次数等
private Site site = Site.me().setRetryTimes(3).setSleepTime(100);
// process是定制爬虫逻辑的核心接口,在这里编写抽取逻辑
public void process(Page page) {
//定义如何抽取页面信息
//爬取干货集中营历史数据,http://gank.io/2017/04/26
page.addTargetRequests(page.getHtml().links().regex("(http://gank\\.io/\\d+/\\d+/\\d+)").all());
page.putField("title", page.getHtml().$("h1").toString());//获取标题
page.putField("content", page.getHtml().$("div.outlink").toString());//获取页面内容
if (page.getResultItems().get("title") == null) {
//跳过没有数据的页面
page.setSkip(true);
}
}
public Site getSite() {
return site;
}
public static void main(String[] args) {
Spider.create(new GankRepoPageProcessor())
.addUrl("http://gank.io")//从该url开始
.addPipeline(new ConsolePipeline())
.thread(5)
.run();
}
}
运行结果如下:
运行结果截图页面元素的抽取说明
对于下载到的Html页面,如何从中抽取到想要的信息?WebMagic里主要使用了三种抽取技术:XPath、正则表达式和CSS选择器。另外,对于JSON格式的内容,可使用JsonPath进行解析。
- XPath
XPath 是一门在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素和属性进行遍历。用于Html也是比较方便的。例如:
page.putField("title", page.getHtml().xpath("//div[@class='blog-heading']/div[@class='title']/text()").toString());
该语句的意思“查找所有Class属性为‘blog-heading’的div,并找它的div子节点(Class属性为‘blog-title’),提取该子节点的文本信息”
- CSS选择器
在 CSS 中,选择器是一种模式,用于选择需要添加样式的元素。
page.putField("content", page.getHtml().$("div.outlink").toString());
该语句的意思“查找所有Class属性为‘outlink’的div”
- 正则表达式
正则表达式是一种特殊的字符串模式,用于匹配一组字符串,就好比用模具做产品,而正则就是这个模具,定义一种规则去匹配符合规则的字符。
page.addTargetRequests(page.getHtml().links().regex("(http://gank\\.io/\\d+/\\d+/\\d+)").all());
- JsonPath
JsonPath是于XPath很类似的一个语言,它用于从Json中快速定位一条内容。WebMagic中使用的JsonPath格式可以参考这里:https://code.google.com/p/json-path/
链接的发现
一个站点的页面是很多的,一开始我们不可能全部列举出来,如何发现后续的链接?
page.addTargetRequests(page.getHtml().links().regex("(http://gank\\.io/\\d+/\\d+/\\d+)").all());
这段代码的分为两部分,page.getHtml().links().regex("(http: //gank\.io/\d+/\d+/\d+)").all()用于获取所有满足"(http: //gank\.io/\d+/\d+/\d+)"这个正则表达式的链接,page.addTargetRequests()则将这些链接加入到待抓取的队列中去。即可完成对该站点的页面爬取。