java爬蟲(二)利用HttpClient和Jsoup庫實現簡單的Java爬蟲程序


jsoup官方文檔:https://www.open-open.com/jsoup/parsing-a-document.htm

一、jsoup簡介

jsoup 是一款Java 的HTML解析器,可直接解析某個URL地址、HTML文本內容。它提供了一套非常省力的API,可通過DOM,CSS以及類似於jQuery的操作方法來取出和操作數據。

 

文檔內容可知道,獲取數據源的方法有三種

 

(1)從一段html代碼字符串獲取:  Document doc = Jsoup.parse(html);

(2)從一個url獲取:          Document doc = Jsoup.connect(url).get();

 

(3)從一個html文件獲取      File input = new File("XXX.html"); 或Document doc = Jsoup.parse(input, "UTF-8", url);

 

二、編碼實踐

0.導入jsoup.jar資源包

 

1.獲取頁面全部代碼

每一個頁面都有相關的前端內容,我們這里就是先分析相關頁面的內容,然后根據標簽來進行分別分類獲取,然后利用java的其余技術來處理你獲取的內容。

首先最基本的,獲取頁面的全部代碼,包含HTML,CSS等內容,這里也以網絡盜版小說網站為例子,進行相關的爬蟲。

package pachong;
 
import java.io.IOException;
 
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
 
public class test{
    //第一個,完整爬蟲爬下來內容
    public static void get_html(String url){
        try {
            Document doc = Jsoup.connect(url).get();
            System.out.println(doc);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        String url = "http://news.tjut.edu.cn/yw.htm";    
        get_html(url);
    }
 
}

運行結果如下

 

 

2.用相關class、id、tag的方法解析我們需要的數據

方法總結:

 

 

package debug;


import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class test {
    //第一個,完整爬蟲爬下來內容
    public static void get_html(String url){
        try {
            Document doc = Jsoup.connect(url).get();
            //得到html中id為content下的所有內容
            Element ele = doc.getElementById("line52564_20");
            //分離出下面的具體內容
            Elements tag = ele.getElementsByTag("td");
            System.out.println(tag);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public static void main(String[] args) {
//        String url = "http://www.biquge5200.com/78_78387/149957687.html";
        String url = "http://news.tjut.edu.cn/yw.htm";
        
        get_html(url);
    }
 
}

輸入如下:

 

 3.通過io操作獲取到某個具體的值

本事例想要獲取的是新聞網站中新聞的總條數

 

 代碼如下

 

package debug;


import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class test {
    
//    實現切割某兩個字之間的字符串
    public static String findstr(String str1,String strstrat,String strend ) {
        String finalstr=new String();
        int strStartIndex = str1.indexOf(strstrat);
        int strEndIndex = str1.indexOf(strend); 
        
        finalstr = str1.substring(strStartIndex, strEndIndex).substring(strstrat.length());
        
        
    return finalstr;
    }
    
    //第一個,完整爬蟲爬下來內容
    public static void get_html(String url){
        try {
            Document doc = Jsoup.connect(url).get();
            //得到html中id為content下的所有內容
            Element ele = doc.getElementById("fanye52564");
            //分離出下面的具體內容
            Elements tag = ele.getElementsByTag("td");
            for(Element e : tag) {
                String title = e.getElementsByTag("td").text();
                String Totals=findstr(title,"共","條");
                System.out.println(Totals);
            }
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public static void main(String[] args) {
        String url = "http://news.tjut.edu.cn/yw.htm";
        
        get_html(url);
    }
 
}


//參考文獻https://blog.csdn.net/suqi356/article/details/78547137?depth_1-
//https://www.cnblogs.com/carlo/p/4717947.html

運行結果如下:

 

 

 

接口文檔(https://jsoup.org/apidocs/overview-summary.html)也能搜到。

 

jsoup 是一款Java 的HTML解析器,可直接解析某個URL地址、HTML文本內容。它提供了一套非常省力的API,可通過DOM,CSS以及類似於jQuery的操作方法來取出和操作數據。

 

文檔內容可知道,獲取數據源的方法有三種

 

(1)從一段html代碼字符串獲取:  Document doc = Jsoup.parse(html);

(2)從一個url獲取:          Document doc = Jsoup.connect(url).get();

(3)從一個html文件獲取      File input = new File("XXX.html"); 或Document doc = Jsoup.parse(input, "UTF-8", url);

 

廢話不說,進入正文。

 

每一個頁面都有相關的前端內容,我們這里就是先分析相關頁面的內容,然后根據標簽來進行分別分類獲取,然后利用java的其余技術來處理你獲取的內容。

 

首先最基本的,獲取頁面的全部代碼,包含HTML,CSS等內容,這里也以網絡盜版小說網站為例子,進行相關的爬蟲。

 

 

  1.  
    package pachong;
  2.  
     
  3.  
    import java.io.IOException;
  4.  
     
  5.  
    import org.jsoup.Jsoup;
  6.  
    import org.jsoup.nodes.Document;
  7.  
     
  8.  
    public class Test1 {
  9.  
    //第一個,完整爬蟲爬下來內容
  10.  
    public static void get_html(String url){
  11.  
    try {
  12.  
    Document doc = Jsoup.connect(url).get();
  13.  
    System.out.println(doc);
  14.  
    } catch (IOException e) {
  15.  
    e.printStackTrace();
  16.  
    }
  17.  
    }
  18.  
    public static void main(String[] args) {
  19.  
    String url = "http://www.biquge5200.com/78_78387/149957687.html";
  20.  
    get_html(url);
  21.  
    }
  22.  
     
  23.  
    }


輸出的結果如下:

 

因為consle不能全部截圖,我就截圖了一部分,從這里就能看到完整的前端內容。

 

而我們只需要里面的小說內容,而對於什么樣式,腳本等等之類的東西並不是我們需要的,於是我們先找到小說正文內容,根據正文內容來處理。

 

 

我們分析正文內容發現,正文內容全部是被一組id為content的div包含的,對於其他內容,我們並不需要,只需要id為content的div內容里的數據,於是我們能不能只要這里面的東西的。

 

而查詢jsoup,我們發現確實是有相關獲取class,id,tag的方法的,可以利用這些發現來獲取我們需要的數據,於是第二個例子就出現了。

 

 

  1.  
    package pachong;
  2.  
     
  3.  
    import java.io.IOException;
  4.  
     
  5.  
    import org.jsoup.Jsoup;
  6.  
    import org.jsoup.nodes.Document;
  7.  
    import org.jsoup.nodes.Element;
  8.  
    import org.jsoup.select.Elements;
  9.  
     
  10.  
    public class Test2 {
  11.  
    //第二個,選擇內容爬下來
  12.  
    public static void get_html(String url) {
  13.  
    try {
  14.  
    Document doc = Jsoup.connect(url).get();
  15.  
    //得到html中id為content下的所有內容
  16.  
    Element ele = doc.getElementById( "content");
  17.  
    //分離出下面的具體內容
  18.  
    Elements tag = ele.getElementsByTag( "div");
  19.  
    System.out.println(tag);
  20.  
    } catch (IOException e) {
  21.  
    e.printStackTrace();
  22.  
    }
  23.  
    }
  24.  
     
  25.  
    public static void main(String[] args) {
  26.  
    String url = "http://www.biquge5200.com/78_78387/149957687.html";
  27.  
    get_html(url);
  28.  
    }
  29.  
    }


他的輸出結果如下圖:

 

 

 

我們發現最基本的內容我們已經拿到,現在就是需要對立面的內容來簡單的處理一下。這就很簡單了,轉換成字符串類型的,利用字符串的相關方法來處理這個。

 

如果我們要導出來保存本地,就可以利用java的io來處理相關數據並保存。

 

  1.  
    package pachong;
  2.  
     
  3.  
    import java.io.File;
  4.  
    import java.io.FileWriter;
  5.  
    import java.io.IOException;
  6.  
     
  7.  
    import org.jsoup.Jsoup;
  8.  
    import org.jsoup.nodes.Document;
  9.  
    import org.jsoup.nodes.Element;
  10.  
    import org.jsoup.select.Elements;
  11.  
     
  12.  
    public class Test2 {
  13.  
    //第二個,選擇內容爬下來並保存到自己電腦
  14.  
    public static void get_html(String url) {
  15.  
    try {
  16.  
    Document doc = Jsoup.connect(url).get();
  17.  
    //得到html中id為content下的所有內容
  18.  
    Element ele = doc.getElementById( "content");
  19.  
    //分離出下面的具體內容
  20.  
    Elements tag = ele.getElementsByTag( "div");
  21.  
    //System.out.println(tag);
  22.  
    String text = tag.text();
  23.  
    //替換里面的空格為換行
  24.  
    String needs = text.replace( "  ", "\n");
  25.  
    //得到整個html里面的tittle,方便爬蟲下來的txt命名文件名
  26.  
    Elements titlehtml = doc.getElementsByTag( "title");
  27.  
    String tittle = titlehtml.text();
  28.  
    //去掉多余的txt文件命名的文字
  29.  
    String head=tittle.substring( 0,tittle.length()- 7);
  30.  
    File file = new File( "D:\\"+head+ ".txt");
  31.  
    FileWriter fw = new FileWriter(file);
  32.  
    fw.write(needs);
  33.  
    fw.close();
  34.  
    } catch (IOException e) {
  35.  
    e.printStackTrace();
  36.  
    }
  37.  
    }
  38.  
     
  39.  
    public static void main(String[] args) {
  40.  
    String url = "http://www.biquge5200.com/78_78387/149957687.html";
  41.  
    get_html(url);
  42.  
    }
  43.  
    }

 

那上面只是簡單的一篇小說,如果我們想把全本小說全部下載到我們的電腦里並保存下來,那又如何處理呢?

 

我們先看看整個目錄的小說里對前端內容的分析,我們發現,其實每個章節的內容都在一個id為list的div下,那面根據上面的經驗來說,我們就拿list來獲取。

 

然后獲取到后,我們根據超鏈接標簽a來遍歷,獲取到數據后,在循環里打開頁面,然后爬蟲下載下來就可以了。

 

 

  1.  
    package pachong;
  2.  
     
  3.  
    import java.io.File;
  4.  
    import java.io.FileWriter;
  5.  
    import java.io.IOException;
  6.  
     
  7.  
    import org.jsoup.Jsoup;
  8.  
    import org.jsoup.nodes.Document;
  9.  
    import org.jsoup.nodes.Element;
  10.  
    import org.jsoup.select.Elements;
  11.  
     
  12.  
    public class Test3 {
  13.  
    //第三個,批量選擇內容爬下來並保存到自己電腦
  14.  
    public static void get_html(String url) {
  15.  
    try {
  16.  
    //模仿瀏覽器訪問
  17.  
    Document doc = Jsoup.connect(url)
  18.  
    .userAgent( "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; MALC)")
  19.  
    .timeout( 999999999)
  20.  
    .get();
  21.  
    //得到html中id為list下的所有內容
  22.  
    Element ele = doc.getElementById( "list");
  23.  
    //得到html中id為list下,同時標簽為a的下面數據
  24.  
    Elements tag = ele.getElementsByTag( "a");
  25.  
    String taghref, tagtext;
  26.  
    for ( int i = 9; i < tag.size(); i++) {
  27.  
    try {
  28.  
    //當前循環時間睡眠為10
  29.  
    Thread.currentThread().sleep( 5000);
  30.  
    taghref = tag.get(i).attr( "href");
  31.  
    tagtext = tag.get(i).text();
  32.  
    Document docs = Jsoup.connect(taghref)
  33.  
    .userAgent( "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; MALC)")
  34.  
    .timeout( 999999999)
  35.  
    .get();
  36.  
    Element eles = docs.getElementById( "content");
  37.  
    Elements tags = eles.getElementsByTag( "div");
  38.  
    String texts = tags.text().replace( "  ", "\r\n\r\n");
  39.  
    String tittle = docs.getElementsByTag( "title").text();
  40.  
    String head = tittle.substring( 0, tittle.length() - 7);
  41.  
    File file = new File( "D:\\Desktop\\hanxiang\\" + head + ".txt");
  42.  
    FileWriter fw = new FileWriter(file);
  43.  
    fw.write(texts);
  44.  
    fw.close();
  45.  
    } catch (Exception e) {
  46.  
    e.printStackTrace();
  47.  
    }
  48.  
    }
  49.  
     
  50.  
    } catch (IOException e) {
  51.  
    e.printStackTrace();
  52.  
    }
  53.  
    }
  54.  
     
  55.  
    public static void main(String[] args) {
  56.  
    String url = "http://www.biquge5200.com/78_78387/";
  57.  
    get_html(url);
  58.  
    }
  59.  
    }

 

 

這里有幾個地方解釋:
1.先說.userAgent("Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; MALC)").timeout(999999999)
           .userAgent表示是模擬自己是瀏覽器訪問,防止反爬蟲網站對爬蟲程序的禁止訪問;
           .timeout(999999999)個人理解是延時訪問,也是防止反爬蟲網站對爬蟲程序的禁止訪問;


2.為何循環從9開始,而不是從0或者1開始呢?
           因為我們看小說章節目錄發現,前面九章是最新更新的九章,而這九章我們並不需要,因為我們后面的循環可以抓到最后的九章,所以從9開始,或者在循環結束那減去9也可以的。因人而異。


3.為何要寫個Thread.currentThread().sleep(5000);來對循環睡眠:
            因為你頻繁訪問,哪怕你偽裝成瀏覽器,還是會對服務器性能等方面造成影響,服務器會對這種連接拒絕,而睡眠線程,這樣的話,就模擬一個人正在瀏覽小說,5秒看完一篇小說是比較很正常的,這樣,你才能把上百上千的小說下載下來。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM