java的簡單網絡爬蟲(爬取花瓣網的圖片)


 

因為本人對爬蟲比較感興趣,加上之前也寫過一些簡單的python爬蟲,所以在學完java基礎后寫了一個簡單的網絡圖片爬蟲。廢話不多說直接上過程代碼。(爬取的圖源來自花瓣網:https://huaban.com/boards/favorite/beauty/

源url頁面分析

拿到爬取的源url,首先是分析頁面哪些東西是要爬取的,這個頁面是美女分類的畫板頁面,這里我們要爬的就是要爬取某個畫板下面的所有圖片。這里為了簡單爬取我就選取了該頁面推薦的幾個畫板。查看本頁面源碼可以很快找到推薦畫板的url資源,如下圖。

可以看到要爬取目標資源就存在這個app.page["suggests"]里面,可以通過正則拿到這些url,然后依次去訪問這些url,得到畫板頁面。

畫板url的爬取

 這里先寫一個靜態的獲取頁面html的方法

public static StringBuffer getHtml(String url) throws Exception{
        URL url1 = new URL(url);
        URLConnection connection = url1.openConnection();
        InputStream is = connection.getInputStream();
        BufferedReader bw = new BufferedReader(new InputStreamReader(is));
        StringBuffer sb = new StringBuffer();
        while (bw.ready()){
            sb.append(bw.readLine()).append("\n");
        }
        bw.close();
        is.close();
        return sb;
    }

編寫爬取畫板url的正則,如下

tring suggestsRegex = "app.page\\[\"suggests\"\\] = \\{.*\\}";
        String urlRegex = "\"url\":\".*?\"";
        StringBuffer html = Util.getHtml("https://huaban.com/boards/favorite/beauty/");
        Matcher suggestsMatcher = Pattern.compile(suggestsRegex).matcher(html);
        while (suggestsMatcher.find()){
            Matcher urlMatcher = Pattern.compile(urlRegex).matcher(suggestsMatcher.group());
            while (urlMatcher.find()){
                System.out.println(urlMatcher.group());
            }
        }

可以得到下面的結果:

但是這些url並不全是我們需要的畫板url,比如上面第三條url會跳轉到另一個分類頁面,而且有些url協議為http有些為https,這里測試發現協議為http的都會重定向到其對應的https頁面,所以這里我們為了方便提取url,只提取目標中的畫板id,就是數字部分,然后手動添加其余的部分,修改上面的部分代碼如下。

while (urlMatcher.find()) {
//                System.out.println(urlMatcher.group());
                String urlStr = urlMatcher.group();
                if (urlStr.contains("boards")) {
                    Matcher matcherId = Pattern.compile("[\\d]+").matcher(urlStr);
                    String id = "";
                    while (matcherId.find()) {
                        id = matcherId.group();
                    }
                    String url = "https://huaban.com/boards/" + id;
                    System.out.println(url);
                }
            }

此時就得到了推薦畫板的url了。

畫板頁面分析

 這里用getHtml方法得到的畫板頁面html和在瀏覽器中查看的源碼並不相同,其中源碼部分的script代碼被解析為了html代碼被返回回來了。所以這里我們只能看控制台打印回來的代碼來找到圖片的url。此處就不作太多介紹,具體可自行嘗試查看。

圖片url的爬取

這里也是采用正則來爬(網上有選擇器的方法來爬取目標資源,可自行百度),先是獲取所有img標簽的內容再進一步正則查詢其中符合圖片url特征的內容。如下

String  get_img_regex = "<img src=\"//hbimg.*?/>";
        String  get_src_regex = "\"//hbimg.huabanimg.com/.*?\"";
        StringBuffer html = Util.getHtml("https://huaban.com/boards/17375733");
        Matcher matcherImg = Pattern.compile(get_img_regex).matcher(html);
        while (matcherImg.find()){
            Matcher matcherSrc = Pattern.compile(get_src_regex).matcher(matcherImg.group());
            while (matcherSrc.find()){
                System.out.println(matcherSrc.group());
            }
        }

通過測試發現末尾位sq75sf的是頭像圖url,末尾為fw236的才是我們需要的圖片url,不過是小圖,我們發現大圖(瀏覽器上點開單個圖片頁面即可查看大圖url)的url只有末尾參數與小圖url不同(大圖末尾是fw658),修改上面部分代碼如下

while (matcherSrc.find()){
                String srcStr = matcherSrc.group();
                if (srcStr.contains("fw236")){
                    String srcUrl = srcStr.substring(1,srcStr.length()-1).replace("fw236","fw658");
                    System.out.println(srcUrl);
                }
            }

最后將得到的數據用列表封裝並返回即可。

圖片下載

URL url = new URL("http://hbimg.huabanimg.com/3bd402c57a727148fce86c193c9d5e93fb48b14b4d760-wF9Y7Z_fw658");
        InputStream is = url.openStream();
        FileOutputStream fos = new FileOutputStream("src/test.png");
        byte buf[] = new byte[1024];
        int length = 0;
        while ((length=is.read(buf))!=-1){
            fos.write(buf,0,length);
        }
        fos.close();
        is.close();

代碼優化與完善

這里簡單的說一下程序優化的方案。由於有多個畫板,所以每個畫板可以開啟一個線程進行爬取。還有就是每個畫板大約只能爬到40張左右圖片,那是因為頁面采用Ajax加載資源(這個我也不太懂,可自行百度),可用代碼模擬加載數據進而獲取到所有圖片。(這里每次加載請求的參數是每個頁面最后一張圖片的id,可自行嘗試完成)

 

寫在最后

 因為本人還是個java初學者菜鳥,所以代碼肯定是有漏洞和不足的地方歡迎大家指出共同學習,謝謝。

項目源碼:https://github.com/zengtao614/JavaCrawler

 


免責聲明!

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



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