Java爬取中国高校的信息,实现高效下拉选

事情背景

最近帮朋友做一个小项目,里面涉及到中国高校信息的下拉选。就去网上搜索一下相关信息,总结了一下,还是把这些信息控制在自己的手里比较好,就尝试用Jsoup爬取中国高校信息。

准备工作

1.爬取网址:校园信息库

            2.创建一个springboot项目,引入Jsoup的依赖。

<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!--jsoup-->
		<dependency>
			<groupId>org.jsoup</groupId>
			<artifactId>jsoup</artifactId>
			<version>1.10.3</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
	</dependencies>

3.数据库表

开始撸代码

因为我把城市信息和高校信息分别存在两张表,所以爬取高校信息分成两步。

1.爬取城市信息。

上代码:

Document doc = Jsoup.connect(url).get();
//取出所有的城市,并编号
cityMap = new CollegeSpider().cityInfo(doc,cityMap);
//保存城市信息
citySave(cityMap);

 

/**
     * 爬取城市信息
     * @param doc
     * @param cityMap
     * @return
     */
    public Map<String,Integer> cityInfo(Document doc, Map<String,Integer> cityMap){
        //获取城市列表元素
        Elements cityList = doc.getElementsByClass("ch-select ch-hide").get(0).children();
        //跳过第一行
        boolean isFirst = true;
        for(Node city : cityList){
            if(isFirst){
                isFirst = false;
                continue;
            }
            Integer cityNum = ((Element) city).attr("value")==null? 10000 : Integer.parseInt(((Element) city).attr("value"));
            String cityName = city.childNodes().get(0).outerHtml();
            //组装map
            cityMap.put(cityName.trim(),cityNum);
        }
        return cityMap;
    }
/**
     * 保存城市信息
     * @param cityMap
     */
    private void citySave(Map<String, Integer> cityMap) {
        //map迭代器
        Iterator<Map.Entry<String, Integer>> entries = cityMap.entrySet().iterator();
        //存库列表
        List<CityEntity> citys = new ArrayList<>();
        while (entries.hasNext()) {
            Map.Entry<String, Integer> entry = entries.next();
            citys.add(new CityEntity(entry.getValue(),entry.getKey()));
        }
        //先删除所有
        cityRepository.deleteAll();
        //存库
        cityRepository.saveAll(citys);
    }

 

2.爬取高校信息

上代码:

 //爬取数据(高校信息表格)
            Integer start = 0;
            while (true){
                String paramUrl = url + "?start="+start;
                Document docs = Jsoup.connect(paramUrl).get();
                Elements collegeList = docs.getElementsByClass("ch-table");
                //拿到需要表格的页面元素集合
                String html = collegeList.get(0).children().get(0).children().get(1).children().get(0).childNodes().get(0).outerHtml();
                if("很抱歉,没有找到您要搜索的数据!".equals(html)){
                    break;
                }else {
                    Elements collegeElements = collegeList.get(0).children().get(0).children();
                    colleges = new CollegeSpider().collegeInfo(collegeElements,colleges,cityMap);
                }
                start += 20;
                //休眠一秒
                Thread.sleep(1000);
            }
            //先删除再保存高校数据
            collegeRepository.deleteAll();
            collegeRepository.saveAll(colleges);
 /**
     * 爬取高校信息
     * @return
     */
    public List<CollegeEntity> collegeInfo(Elements collegeElements, List<CollegeEntity> collegList, Map<String,Integer> cityMap){
        //遍历表格每一行
        boolean isFirst = true;
        for(Element element : collegeElements){
            //跳过表格第一行
            if(isFirst){
                isFirst = false;
                continue;
            }
            //从第二行开始遍历
            Elements elements = element.getAllElements();
            //记列数
            int column = 0;
            //遍历每一列
            CollegeEntity college = new CollegeEntity();
            for(Element elem : elements){
                if(null == elem.children() || elem.children().size() ==0){
                    //1.学校名
                    if(column == 0){
                        college.setName(elem.childNodes().get(0).outerHtml().trim());
                    }else if(column == 1){
                        college.setCityId(cityMap.get(elem.childNodes().get(0).outerHtml().trim()));
                    }else if(column == 4){//本科
                        college.setRecord(elem.childNodes().get(0).outerHtml());
                    }else if(column == 5){//985|211
                        if(elem.childNodes().size() != 0){
                            college.setFeatures(elem.childNodes().get(0).outerHtml());
                        }
                    }else if(column == 6){//|211
                        if(StringUtils.isBlank(college.getFeatures())){
                            college.setFeatures(elem.childNodes().get(0).outerHtml());
                        }else {
                            college.setFeatures(college.getFeatures() +"|"+elem.childNodes().get(0).outerHtml());
                        }
                    }else if(column == 7){//是否是研究生院校
                        if(elem.tag().getName().contains("i")){
                            college.setInstitute(true);
                        }else {
                            college.setInstitute(false);
                        }
                    }
                    column ++;
                }
            }
            //保存高校列表
            collegList.add(college);
            log.info(college.toString());
        }
        return collegList;
    }

运行结果:

至此,我的目的已经达到,接下来写一个高校下拉选接口即可。

总结:

1.Jsoup适合静态网页信息的抓取。

2.难点在于找到想要的信息的具体节点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乐闻x

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值