本文主要分享的是关于Java爬虫技术其中一个方式 ==> Jsoup
1、Jsoup简介
推开技术大门,爬虫技术琳琅满目,而今天要分享的Jsoup是一款Java的HTML解析神器,,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API。可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。
。关于Jsoup的详细介绍,不赘述,以下是 官方文档,自行查阅。我们直接上代码。
2、代码分享(真实爬取一个政府采购网:中国政府采购网,按照关键词搜索的公告)
注意的点:爬虫的是要爬取大量列表信息的,这就要考虑到判断总页数,翻开每一页,遍历每一条数据,还要在F12模式下,查看网页发起请求的格式,查看URL传递参数的加密方式,如果请求失败了,如何处理 等等
package com.Utill; import com.alibaba.fastjson.JSONObject; import com.ckms.comp.manager.im.govManage.service.GovManageServiceImpl; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.*; import java.util.*; /** * @Author: * @Date: 2019/10/1 13:43 * @Describe: */ public class JsoupDemo { private static final Logger logger = LoggerFactory.getLogger(JsoupDemo.class); private String keyword = null; private String endtime = null; private String begintime = null; private String zzUrl = null; private boolean start = false; int isSize = 1; Integer pageSize = 0; Integer timeType = 6; // 时间类型 6: 指定时间 5:近半年 0:今日 4:近3月 /** * 爬虫调用主方法 * * @param id 关键词的饿id * @param kw 关键词 * @param startTime 开始时间 * @param endTime 结束时间 */ public void fetch(Integer id, String kw, String startTime, String endTime) { logger.info("开始拉取网站数据》》》》》》》》》》》》》》》》》》》》》》》》》》》"); Integer totalSize = null; try { keyword = toUtf8String(kw); begintime = startTime.replace("/", "%3A"); endtime = endTime.replaceAll("/", "%3A"); pageSize = 1; zzUrl = "http://search.ccgp.gov.cn/bxsearch?searchtype=1&page_index=" + pageSize + "&bidSort=0&buyerName=&projectId=&pinMu=0&bidType=0&dbselect=bidx&kw=" + keyword + "&start_time=" + begintime + "&end_time=" + endtime + "&timeType=" + timeType + "&displayZone=&zoneId=&pppStatus=0&agentName="; start = true; //获取总页数 totalSize = fetchHomePageUrl(zzUrl); if (totalSize != null && totalSize > 0) { while (start) { if (isSize > totalSize) { start = false; } else { pageSize = isSize; zzUrl = "http://search.ccgp.gov.cn/bxsearch?searchtype=1&page_index=" + isSize + "&bidSort=0&buyerName=&projectId=&pinMu=0&bidType=0&dbselect=bidx&kw=" + keyword + "&start_time=" + begintime + "&end_time=" + endtime + "&timeType=" + timeType + "&displayZone=&zoneId=&pppStatus=0&agentName="; //开始遍历每一页数据 fetchingPageUrl(id, isSize, zzUrl); isSize++; } } } else { logger.info("关键词:" + kw + "没有查询到相关数据-" + new Date()); isSize = 1; } } catch (Exception er) { logger.error("========================获取数据失败,重新获取中.....================================="); } } //URL汉字转码 public static String toUtf8String(String s) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (c >= 0 && c <= 255) { sb.append(c); } else { byte[] b; try { b = String.valueOf(c).getBytes("utf-8"); } catch (Exception ex) { System.out.println(ex); b = new byte[0]; } for (int j = 0; j < b.length; j++) { int k = b[j]; if (k < 0) k += 256; sb.append("%" + Integer.toHexString(k).toUpperCase()); } } } return sb.toString(); } // 首次访问url ,需查找当前查询词所在的总页数 public Integer fetchHomePageUrl(String ur) { Integer size = null; try { //maxBodySize : 0 不限制大小, 1: 1m userAgent: 伪装成浏览器 Document doc = Jsoup.connect(ur).header("Accept-Encoding", "gzip, deflate") .userAgent("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31") .maxBodySize(0).timeout(600000).get(); Elements eli = doc.select(".vT-srch-result-list-con2 .vT-srch-result-list .vt-srch-result-list-bid>li"); if (eli.size() > 0) { //获取分页html Elements allElements = doc.select(".vT_z .pager>script"); if (allElements.size() > 0) { String pager = allElements.get(0).childNodes().toString(); String startStr = pager.substring(7, pager.length()); String objectStr = startStr.substring(0, startStr.lastIndexOf(")")); //string转json对象 JSONObject jsonObject = JSONObject.parseObject(objectStr); // 共有多少页 size = Integer.valueOf((Integer) jsonObject.get("size")); } } } catch (IOException e1) { e1.printStackTrace(); } return size; } // 遍历页数 public void fetchingPageUrl(Integer id, Integer pageSize, String fetchUrl) { Integer is_homePage = 1; // 0 : 首页 1: 否 String noticeOutline = null; try { Document pDoc = Jsoup.connect(fetchUrl).header("Accept-Encoding", "gzip, deflate") .userAgent("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31") .maxBodySize(0) .timeout(600000).get(); //根据css样式 获取当前页的所有url Elements elements = pDoc.select(".vT_z .vT-srch-result-list-bid>li"); // Elements hrefs = doc.select("a[href]"); //遍历当前页的所有url for (Element element : elements) { //根据Jsoup解析,解析每一页的详细数据,见下一篇博客 } } catch (Exception e) { e.printStackTrace(); } } }