1. 程式人生 > >Java網路爬蟲(八)--使用多執行緒進行百度圖片的抓取

Java網路爬蟲(八)--使用多執行緒進行百度圖片的抓取

宣告:如需轉載本篇文章,請進行私聊並在文章首處註明出處,本程式碼未經授權不可用於獲取商業價值,否則後果將由自己承擔。

這次的需求大概是從百度圖片裡面抓取任意的分類的圖片,考慮到有些圖片的資源不是很好,並且由於百度搜索越到後面相關度會越來越低,所以我將每個分類要爬的資料量控制在了600,實際爬下來,每個分類也就是500左右的圖片。

實現架構

先來看一下本次程式碼的實現架構:

這裡寫圖片描述

  • htmlparse裡面的兩個類主要負責對網頁進行請求以返回實體,並且對實體進行解析,拿到自己想要的json資料和每個圖片的連結。
  • httpbrowser裡面主要構建了要爬取的url,從百度圖片的分頁到具體的每個圖片的url。
  • mainmethon主要就是main方法了。
  • savefile主要是將爬取的圖片進行檔案的儲存,以每個圖片的url最後面的一串字串為檔名,然後將它儲存到自己建立的目錄之中。

我們來看一下main方法:

package mainmethon;

import httpbrowser.CreateUrl;
import savefile.ImageFile;

import java.util.ArrayList;
import java.util.List;

import static java.lang.System.out;

/**
 * Created by hg_yi on 17-5-16.
 *
 * 測試資料:image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=bird&
 *
 * 在多執行緒進行下載時,需要向執行緒中傳遞引數,此時有三種方法,我選擇的第一種,設計構造器
 */
public class major { public static void main(String[] args) { int sum = 0; List<String> urlMains = new ArrayList<>(); List<String> imageUrls = new ArrayList<>(); //首先得到10個頁面 urlMains = CreateUrl.CreateMainUrl(); out.println(urlMains.size()); for
(String urlMain : urlMains) { out.println(urlMain); } //使用Jsoup和FastJson解析出所有的圖片源連結 imageUrls = CreateUrl.CreateImageUrl(urlMains); for(String imageUrl : imageUrls) { out.println(imageUrl); } //先創建出每個圖片所屬的資料夾 ImageFile.createDir(); int average = imageUrls.size()/10; //對圖片源連結進行下載(使用多執行緒進行下載)建立程序 for(int i = 0; i < 10; i++){ int begin = sum; sum += average; int last = sum; Thread image = null; if(i < 9) { image = new Thread(new ImageFile(begin, last, (ArrayList<String>) imageUrls)); } else { image = new Thread(new ImageFile(begin, imageUrls.size(), (ArrayList<String>) imageUrls)); } image.start(); } } }

對於main方法中的每個方法的解釋已經很清楚了,在這裡我就不進行詳細的說明了。

記錄一下本次程式碼的坑點

對於這個程式碼的實現,當時bug改的時間最長的就是這一段程式碼了:

try {
    URL url = new URL(imageUrls.get(i));
    URLConnection conn = url.openConnection();
    conn.setConnectTimeout(1000);
    conn.setReadTimeout(5000);
    conn.connect();
    inputStream = conn.getInputStream();
} catch (Exception e) {
    continue;
}

這段程式碼的主要目的就是下載圖片,對圖片的源地址進行請求,然後將其作為輸入流,在沒有進行超時設定和異常處理之前,是會進行連結超時和read time out這兩個錯誤的,當時還使用了httpclient進行了改寫,結果還是不正確,最後使用了超時設定,並且對於超過時間還沒有進行url請求的,就進行下一個url的請求,直接放棄這次請求,本來打算爬600張圖片,最後只能爬500張,原因就是在這。

原始碼連結