背景
相信大家都对爬虫或多或少对有一个概念,百度百科描述为:爬虫是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。
网上大部分的爬虫框架,都很好都整合了制定规则和自动抓取都两个功能。但也因为其整合性高,上手难度也随之提升。目前github上面星比较高的爬虫框架有:Apache Nutch
webmagic
WebCollector
gecco
…
但是我最想为大家介绍的是下面这个。
retrofit-crawler
retrofit-crawler简介
retrofit-crawler是一款基于retrofit和jsoup编写的爬虫api,它提供了一个和面向接口编程一样的代码编写风格。
依赖
com.github.qlone
retrofit-crawler
1.0.0
创建一个爬虫规则
举个例子,当我要获取百度新闻首页的新闻标题和url时,我通过对页面对一顿猛如虎的分析,我获得了一个接口:
public interface Baidu {
@POST("/")
Call html();
}
public class Accept {
@Select("div#pane-news li")
private List news;
}
public class News {
@Text("a")
private List title;
@Attr(value = "a",attr = "href")
private List url;
}
有没有发现,这个和我们接收一个json参数的HTTP的调用是一样的风格!!!
其中div#pane-news li是jsoup中获取element的语法。有想进一步学习jsoup的同学可以看这篇博客:
创建一个实例
接下来,用过retrofit的小伙伴一定知道我想说的,没错就是创建一个实例
RetrofitCrawler retrofitCrawler = new RetrofitCrawler.Builder()
.baseUrl("https://news.baidu.com")
.build();
Baidu baidu = retrofitCrawler.create(Baidu.class);
其中baidu就是我们需要的那个对象了,通过调用baidu.html()我们可以获得一个Call对象。这个对象包含了一个请求需要的所有参数,我们可以选择同步调用或者异步调用。这里我选择同步调用,完整代码如下:
public class Main {
public static void main(String[] args) throws IOException {
RetrofitCrawler retrofitCrawler = new RetrofitCrawler.Builder()
.baseUrl("https://news.baidu.com")
.build();
Baidu baidu = retrofitCrawler.create(Baidu.class);
Call html = baidu.html();
Response execute = html.execute();
Accept accept = execute.body();
for(News news: accept.getNews()){
System.out.println(String.format("title:%s url:%s",news.getTitle(),news.getUrl()));
}
}
}
最终输出结果如下:
其他功能
和retrofit一样在方法参数上面,retrofit-crawler提供了一些注解,因此可以做到适应变化多端的HTTP请求情况@Body
@Header
@HeaderMap
@Query
@QueryMap
@Cookie
@CookieMap
@RelativeUrl
如:
public interface Baidu {
@POST()
Call guonei(@RelativeUrl String relative);
}
同时在结果解析上面,retrofit-crawler提供了另外一些注解:@Select
@Text
@Attr
@Data
@Html
@OuterHtml
了解Jsoup的同学立马就发现,这和Jsoup的Element对象提供的方法是一一对应的。