WebMagic的设计参考了业界最优秀的爬虫Scrapy,而实现则应用了HttpClient、Jsoup等Java世界最成熟的工具。其官网地址:http://webmagic.io/docs/zh/posts/ch1-overview/
教程内容很丰富,详尽,下面是一个快速使用的例子:
首先是pom文件需要引入
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-core</artifactId>
<version>0.7.3</version>
</dependency>
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-extension</artifactId>
<version>0.7.3</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
如果你之前引入了slf4j,这里需要将slf4j的包排除,免得包冲突。
测试代码如下,里面有详尽的解释:
/**
* @author panmingshuai
* @description
* @Time 2018年3月16日 下午2:46:28
*
*/
public class TestGithub implements PageProcessor {
// 部分一:抓取网站的相关配置,包括编码、抓取间隔、重试次数等
private Site site = Site.me().setRetryTimes(3).setSleepTime(1000);
@Override
// process是定制爬虫逻辑的核心接口,在这里编写抽取逻辑
public void process(Page page) {
// 部分二:定义如何抽取页面信息,并保存下来
page.putField("author", page.getUrl().regex("https://gitee\\.com/(\\w+)/.*").toString());//这里使用了正则匹配
page.putField("url", page.getUrl().toString());
/**
* XPath本来是用于XML中获取元素的一种查询语言,但是用于Html也是比较方便的
* 这里使用了xpath匹配
*/
String projectName = page.getHtml().xpath("//span[@class='project-title']/a[@class='repository']/@href").toString();
if(StringUtils.isNotBlank(projectName)){
String projectName2 = new StringBuilder(projectName).reverse().toString();
projectName2 = projectName2.substring(0, projectName2.indexOf("/"));
String projectName3 = new StringBuilder(projectName2).reverse().toString();
page.putField("projectName", projectName3);
}
if (page.getResultItems().get("projectName")==null){
//如果取不到项目名,说明该页不是项目页,跳过此页
page.setSkip(true);
}
page.putField("readme", page.getHtml().xpath("//span[@class='git-project-desc-text']/text()"));
// 部分三:从页面发现后续的url地址来抓取
/**
* 这段代码的分为两部分,page.getHtml().links().regex("(https://gitee\\.com/[\\w\\-]+/[\\w\\-]+)").all()
* 用于获取所有满足"(https://gitee\\.com/[\\w\\-]+/[\\w\\-]+)"这个正则表达式的链接,
* page.addTargetRequests()则将这些链接加入到待抓取的队列中去。
*/
page.addTargetRequests(page.getHtml().links().regex("(https://gitee\\.com/[\\w\\-]+/[\\w\\-]+)").all());
}
@Override
public Site getSite() {
return site;
}
public static void main(String[] args) throws JMException {
Spider osSpider =
Spider.create(new TestGithub())
/**
* WebMagic用于保存结果的组件叫做Pipeline。例如我们通过“控制台输出结果”这件事也是通过一个内置的Pipeline完成的,
* 它叫做ConsolePipeline。那么,我现在想要把结果用Json的格式保存下来,怎么做呢?
* 只需要将Pipeline的实现换成"JsonFilePipeline"就可以了。
*/
// .addPipeline(new JsonFilePipeline("E:\\webmagic\\"))
.addUrl("https://gitee.com/panmingshuai")
.thread(5)
// .run()
;
/**
* 添加监听器,运行后cmd,使用jconsole.exe调出监听器
*/
SpiderMonitor.instance().register(osSpider);
osSpider.start();
}
}
解释一下代码
page.getUrl().regex("https://gitee\\.com/(\\w+)/.*").toString()
和
page.getHtml().xpath("//span[@class='project-title']/a[@class='repository']/@href")
这两段代码上面一个使用了正则方式匹配内容,下面一个使用了xpath匹配内容,正则就不多说了,xpath的教程可以看看这个:http://www.w3school.com.cn/xpath/xpath_syntax.asp
上面的正则匹配的是以https://gitee.com打头,中间跟了任意个数字,末尾以"."加任意的内容结尾的url,正则匹配可以用来匹配url之类的连接,非常好用。
下面的xpath匹配的是所有属性class为projiect-title的span元素下属性class为repository的a标签的href的值。xpath匹配网页上的具体内容,比如名字,文章之类的很有效。
此外还有css选择器之类的但是我觉得还是这两个选择器好用,而且有了这两个选择器,基本上能完成爬虫所有需要的功能了。
另外这个爬虫的功能是爬取码云上项目的项目名,作者和项目介绍readme。
代码地址:https://gitee.com/panmingshuai/webmagic-demo.git