文章目录
项目背景
1.什么是爬虫
爬虫就是一个模拟人类的请求网络行为的程序。可以自动请求网页,并把数据抓取下来,然后使用一定的规则提取有价值的数据。爬虫的优势就在于可以根据需要批量的获取数据。
2.爬取数据
在awesome-java中的project能看到很多Java中开源的第三方库库/框架,进入项目的具体页面后能够看到该项目的star数、fork数、open_issue数等信息,这里就是通过统计star数、fork数、open_issue数来对项目的活跃程度进行排序,数量越多就说明该项目是更流行的。
核心功能
爬取github
网站里awssome-java
这个网页中所有关于github的项目,并按每天的活跃程度排序
开发环境
Windows 10 + IDEA2019.3 64位操作系统。
应用技术
OkHttp、Jsoup、Gson第三方库,github API,Http协议,Linux系统,Mysql
核心工作
1.需要获取到所有待收集信息的项目列表—OkHttpClient
2.遍历项目的列表,依次获取到每个项目的主页信息,进一步统计该项目的Star数、Fork数和Issues数—Jsoup
3.把获取到的数据存储到数据库中—Mysql
4.写一个简单的网页,通过图表的形式来展示数据库中的信息
开发流程
使用OkHttp第三方库获取页面内容
//1.先创建一个OkHttpClient对象(客户端对象),只要一个程序中包含一个实例即可
// 而Request,Call,Response这些需要每次请求都创建
private OkHttpClient okHttpClient = new OkHttpClient();
public String getPage(String url) throws IOException {
//2.创建一个Request对象
// Java中实例化一个对象有很多种方式
// 可以直接new,也可以使用某个静态的工厂方法来创建实例对象
// 此处的Builder类是一个辅助构造Request对象的类
// Builder中提供的url方法能够设定当前请求的url(可查阅官方文档找到怎么用)
Request request = new Request.Builder().url(url).build();
//3.创建一个Call对象(这个对象负责进行一次网络访问操作)
Call call = okHttpClient.newCall(request);
//4.发送请求给服务器,获取到response对象(获取到响应信息)
Response response = call.execute();
//5.判断响应是否成
if(!response.isSuccessful()){
System.out.println("请求失败!");
return null;
}
return response.body().string();
}
使用Jsoup第三方库分析页面结构,获取项目列表
我们可以通过开发者工具分析页面结构,可以看到入口页面中包含很多li,每个li中又有很多的a标签,a标签中的href属性里的url就是我们想得到的内容。我们将得到的项目列表放入Project类中。
主要使用Jsoup第三方库中的getElementsByTag()
方法
public List<Project> parseProjectList(String html){
ArrayList<Project> result = new ArrayList<>();
// 1. 创建 Document 对象(相当于把一个html字符串转换成Document对象)
Document document = Jsoup.parse(html);
//2.使用getElementsByTag()方法来获取li标签
Elements elements = document.getElementsByTag("li");
//Document对象就对应着一个树形结构,树里的每个标签就是一个Element对象,把很多标签放在一起构成的集合就是Elements
for (Element li : elements) {
// 3.再去获取里面的 a 标签.
Elements allLink = li.getElementsByTag("a");
if (allLink.size() == 0) {
// 当前的这个 li 标签中没有包含 a 标签. 直接忽略掉这个 li
continue;
}
// 一个项目的 li 标签里, 只有一个 a 标签.
Element link = allLink.get(0);//获取到a标签
// 4.输出 a 标签中的内容
// System.out.println(link.text());//获取到a标签中的项目名称
// System.out.println(link.attr("href"));//获取到a标签中href属性中的url
// System.out.println(li.text());//获取到li标签中对项目的描述
// System.out.println("===============================");
String url = link.attr("href");
//剔除不属于gihub上的项目的信息
if (!url.startsWith("https://github.com")) {
// 如果当前这个项目的 url 不是以 https://github.com 开头的, 我们就直接丢弃掉
continue;
}
// if (url.equals("https://github.com/events")
// || url.equals("https://github.community")
// || url.equals("https://github.com/about")) {
// continue;
// }
if (urlBlackList.contains(url)) {
continue;
}
//将获取到的内容添加到project
Project project = new Project();
project.setName(link.text());
project.setUrl(link.attr("href"));
project.setDescription(li.text());
result.add(project);
}
return result;
}