Jsoup学习——某网站爬取(递归实现自动翻页/带参数的请求)

Jsoup是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。

爬取过程

1 网页是基于get请求获取到的,无需携带参数请求资源

Step1: 基于get请求获取Url对于网页的HTML

Connection con = Jsoup.connect(目标网页Url);

Step2:利用Jsoup把Html解析为Document

//这里有时候get()会报错,try... catch 解决
Document document = con.get();

Step3:利用Dom方法获取标题、发布时间、内容等

//获取所有元素中第一个class= "list” 的元素
Element element = document.getElementsByClass("list").first()
//获取 class= "list” 的元素中所有li元素,放在elements对象里
Elements elements = element.getElementsByTag("li")
//遍历取出elements中所有标签中包含的连接
for(Element ele:elements){
//contentUrl为标签href属性中某网站Url后半部分链接
  String contentUrl = ele.getElementsByTag("a").attr("href");
//拼接出完整的detailUrl
  String detailUrl = "某网站Url前半部分" + contentUrl;
//基于get请求获取detailDocument中Html
  Document detailDocument = Jsoup.connect(detailUrl).get();
//利用Dom方法获取详细页面里的标题、日期、内容等。
  String title = detailDocument.getElementsByClass("detail_bigtitle").first().text();
  System.out.println("标题:"+ title);
  String time = detailDocument.getElementsByClass("time").first().text();
//这里导入java实例 SimpleDateFormat,格式化时间
  SimpleDateFormat srtFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  Date date = srtFormat.parse(time);
  System.out.println("日期:"+ date);
  String content= detailDocument.getElementsByClass("detail_txt").first().getElementsByTag("p").text();
  System.out.println("内容:"+ content);
//从标题判断所属类型
//利用余弦相似度计算 
  String caseType = Cosine.getSimilarityList(title);
  System.out.println("案件类型:"+ caseType);
  System.out.println("——————————————————————");  
}

2 网页是基于POST请求,需要携带参数请求资源

利用POST请求,携带请求参数,从接口处获取资源
Connection connect = Jsoup.connect("上图中requestURL");
      // 利用headers
      connect.header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3");
      connect.header("Cookie", "值");
      connect.header("Referer", "值");
      connect.header("Host", "值");
      connect.header("User-Agent", "值");
      connect.header("Upgrade-Insecure-Requests", "1");
      //利用form data
      connect.data("searchField", "值");
      connect.data("keywords", "值");
      //这个pageIndexNow是自动翻页的值,可以不写死,实现爬取的自动翻页
      connect.data("pageIndexNow", "值");
      connect.data("pageSizeNow", "值");
      connect.data("currentSubid", "值");
      connect.data("Type", "值");
      //发送带参数的post请求
      Document document = connect.post();
      System.out.println(document.toString());

上面的代码为通过POST请求方式,document为获取到的HTML,接下来通过操作Dom获取到需要的标题、日期、内容等。在取标签属性的过程中,可以加入判断,看是否能取到链接中href属性,若不为空拼接字符串

 for (Element ele : elements) {
        //取时间
        if (!"案例报送时间".equals(ele.getElementsByTag("td").get(1).text())){
          date = ele.getElementsByTag("td").get(1).text();
        }
        String contentUrl = ele.getElementsByTag("a").attr("href");
        //判断能否取到tr中的a链接,若不为空则拼接字符串
        if (!"".equals(contentUrl) && contentUrl != null) {
          detailUrl = "某网站Url前半部分" + contentUrl;
          //遍历存在list里的第一页的所有案件详情链接,调用detailData函数
          detailData(detailUrl, date);
        }
      }

detailData函数:传递参数(String detailUrl, String date)到函数中,访问通过拼接Url获取到的每一个detailUrl链接中的内容

  public Boolean detailData (String detailUrl, String date) {
    //格式化日期
    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
    Date judgeDate = null;
    try {
      judgeDate = formatter.parse(date);
    } catch (ParseException e) {
      e.printStackTrace();
    }
    //访问每一个拼接好的页面 需要用到带参数的POST请求,具体什么请求看 F13 NetWork里的.
    Connection connectPOST = Jsoup.connect(detailUrl);
    //从拿到的detailUrl截取字符串
    String dbid = detailUrl.substring(36,38);
    String dbname = detailUrl.substring(46,50);
    String sysid = detailUrl.substring(detailUrl.lastIndexOf("=")+1) ;
    String id = dbid + sysid;
    //利用headers
    connectPOST.header("Accept", "值");
    connectPOST.header("Cookie", "值");
    connectPOST.header("Referer", "值");
    connectPOST.header("Origin", "值");
    connectPOST.header("User-Agent", "值");
    connectPOST.header("Content-Type", "值");
    //利用data
    connectPOST.data("dbID", "");
    connectPOST.data("dbName", "");
    connectPOST.data("sysID", "");
    //带参数结束
    Document pageDocument = null;
    try {
      pageDocument = connectPOST.post();
    } catch (IOException e) {
      e.printStackTrace();
    }
    //取标签
    Element divElement = pageDocument.getElementsByClass("wzinfo").first();
    //标题
    System.out.println("id:"+ id);//拼接字符串
    //日期
    System.out.println("日期:"+ judgeDate);
    String title = divElement.getElementsByTag("h3").text();
    System.out.println("标题:"+ title);
    //详情
    List contentList = new ArrayList<>();
    String content = null;
    Elements conElement = divElement.getElementsByClass("contentspan").tagName("p");
    for (Element ele : conElement){
      content = ele.getElementsByTag("p").text();
      contentList.add(content);
    }
    System.out.println("详情:"+ contentList);
    System.out.println("-------------------------------------------------------------------");
    return true;
  }

解释这里为什么需要从拼接好的截取detailUrl中截取字符串呢?是因为在发送POST请求的过程中,动态获取detailUrl中的字符串作为请求参数,如下图:


POST请求的

某网站从DetailUrl中动态获取

3.实现递归翻页

你可能感兴趣的:(Jsoup学习——某网站爬取(递归实现自动翻页/带参数的请求))