爬虫项目 Java-GitHub Crawler

本文介绍了一个使用Java实现的GitHub爬虫项目,通过jsoup解析HTML获取项目链接,利用GitHub API获取项目详细信息,并用gson解析数据。数据存储采用JDBC操作MySQL。在遇到分析页面耗时较长的问题后,通过引入多线程优化,测试发现10个线程时效率最佳,实现了项目信息的快速抓取和展示。
摘要由CSDN通过智能技术生成

文章目录


#一、项目简介
该项目基于 okhttp3、jsoup、gson 第三方库对 GitHub 上的 awesome-java 项目进行爬取并获取各个子项目的相关信息(Star收藏数、Fork分支数、Issues问题数),然后根据 Star 数从高到低的顺序进行排序表示项目的活跃程度,并通过 ECharts 图表框架制作一个简易的 Star 日榜,实现一个类似于 “GitHub趋势” 的功能。 在这里插入图片描述
二、主要模块
1.获取页面: 向服务器发送请求,通过第三方库 okhttp 获取指定 url 对应的 html 页面

    public String getPage(String url) throws IOException {
   
        //1.创建一个 OkHttpClient 对象
        okHttpClient = new OkHttpClient();
        //2.创建一个 Request 对象
        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();
    }

2.分析页面
1.通过第三方库 jsoup 解析 html 页面结构,生成 document 对象(树形结构的文档),使用 getElementsByTag() 获取< li >,进一步获取< a >,< a >中 href 属性里的 url 就是我们需要统计的项目主页链接,存储到 Project 对象中

    public List<Project> parseProjectList(String html) {
   
        ArrayList<Project> result = new ArrayList<>();
        //1.使用 parse() 将 html 解析为 document 对象
        Document document = Jsoup.parse(html);
        //2.使用 getElementsByTag() 获取所有的<li>
        Elements elements = document.getElementsByTag("li");    
        for (Element li : elements) {
   
            //3.获取<li>中的<a>
            Elements allLink = li.getElementsByTag("a");
            if (allLink.size() == 0) {
      
                continue;
            }
            Element link = allLink.get(0);  
            //4.获取 href 属性中的内容
            String url = link.attr("href");
            if (!url.startsWith("https://github.com")) {
       
                continue;
            }
            if (urlBlackList.contains(url)) {
      
                continue;
            }
            //5.存储到 Project 中
            Project project = new Project();
            project.setName(link.text());
            project.setUrl(link.attr("href"));
            project.setDescription(li.text());
            result.add(project);
        }
        return result;
    }

2.遍历项目列表,通过 GitHub 官方提供的 API 获取项目信息,第三方库 gson 进行解析,获取项目数据
通过 url 获取仓库名,例如 https://github.com/doov-io/doov => doov-io/doov

    public String getRepoName(String url) {
   
        int lastOne = url.lastIndexOf("/");
        int lastTwo = url.lastIndexOf("/", lastOne - 1);
        if (lastOne == -1 || lastTwo == -1) {
   
            System.out.println("当前 url 不合法");
            return null;
        }
        return url.substring(lastTwo + 1);
    }

通过 GitHub API 获取仓库的项目信息,例如 https://api.github.com/repos/doov-io/doov

    public String getRepoInfo(String repoName) throws IOException {
   
        String username = "huangwu1026";
        String password = "DiL971026";
        //进行身份验证
        String credential = Credentials.basic(username, password);   
        String url = "https://api.github.com/repos/" + repoName;
        Request request = new Request.Builder().url(url).header("Authorization", credential).build();
        Call call = okHttpClient.newCall(request);
        Response response = call.execute();
        if (!response.isSuccessful()) {
   
            System.out.println("请求失败! url = " + url);
            return null;
        }
        return response.body().string();
    }

通过第三方库 gson 解析页面,将获取项目数据(star、fork、issues)存储到 Project 对象中

    public void parseRepoInfo(String jsonString, Project project) {
   
    	//TypeToken 是数据类型转换器
        Type type = new TypeToken<HashMap<String, Object>>() {
   
        }.getType();
        //将 Json 数据转换为对象
        HashMap<String, Object> hashMap = gson.fromJson(jsonString, type);
        Double starCount = (Double) hashMap.get("stargazers_count");
        project.setStarCount(starCount.intValue());
        Double forkCount = (Double) hashMap.get("forks_count");
        project.setForkCount(forkCount.intValue());
        Double openedIssueCount = (Double) hashMap.get("open_issues_count");
        project.setOpenIssueCount(openedIssueCount.intValue());
    }

Project 类用于存储

	@Getter
    @Setter
    @ToString
	public class Project {
   
	    //项目名字,对应<a>中的内容
	    private String name;
	    //项目主页链接,对应<a>中的 href 属性
	    private String url;
	    //项目描述信息,对应<li>中的内容
	    private String description;
	    //需要统计的数据
	    private int starCount;
	    private int forkCount;
	    private int openIssueCount;
	}

3.数据存储: 通过 JDBC 操作 MySQL 数据库将 Project 对象存储到 project_table 表中
1.设计表结构

	create database java_github_crawler;
	create table project_table(
		name varchar(50),
		url varchar(1024),
		description varchar(1024),
		startCount int,
		forkCount int,
		openedIssueCount int,
		date carchar(128)
	);

2.DBUtil 类管理数据库连接

	public class DBUtil {
   
    	private static String url = "jdbc:mysql://localhost:3306/java_github_crawler?useSSL=true&characterEncoding=UTF-8";
    	private static String username = "root";
    	private static String password = "123456";
    	private static volatile DataSource dataSource = null;
    	//单例模式-懒汉式
	    private static DataSource getDataSource() {
   
	        if (dataSource == null) {
      
	            synchronized (DataSource.class) {
   
	                if (dataSource == null) {
   
	                    dataSource = new MysqlDataSource();
	                    MysqlDataSource mysqlDataSource = (MysqlDataSource) dataSource;
	                    mysqlDataSource.setURL(url);
	                    mysqlDataSource.setUser(username);
	                    mysqlDataSource.setPassword(password);
	                }
	            }
	        }
	        return dataSource;
	    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值