一個抓取知乎頁面圖片的簡單爬蟲

    在知乎上看到一個問題  能利用爬蟲技術作到哪些很酷頗有趣頗有用的事情?發現蠻好玩的,便去學了下正則表達式,之前據說正則表達式蠻有用處的,學完後以爲確實很實用的工具。問題評論下基本都是python寫的爬蟲,我看了下原理,感受爬一個簡單的靜態網頁仍是挺容易的。就是獲取網站html源碼,而後解析須要的字段,最後拿到字段處理(下載)。想起我學java的時候有個URL類好像有這個功能,便去翻了下api文檔,發現URLConnection果真能夠獲取html源碼。html

  首先從核心開始寫,獲取網頁源碼java

package mothed;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
/**
 * 爬取網頁源代碼
 * @author ganhang
 *
 */

public class Spider {
    
    public static String GetContent(String url) {
        // 定義一個字符串用來存儲網頁內容
        String result = "";
        BufferedReader in = null;
        try {
            URL realUrl = new URL(url);
            // 初始化連接
            URLConnection connection = realUrl.openConnection();
            // BufferedReader輸入流來讀取URL的響應
            in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
            // 用來臨時存儲抓取到的每一行的數據
            String line;
            while ((line = in.readLine()) != null) {
                // 遍歷抓取到的每一行並將其存儲到result裏面
                System.out.println(line);
                result += line;
            }
        } catch (Exception e) {
            System.out.println("GetContent出現異常!" + e);
            e.printStackTrace();
        }
        // 使用finally來關閉輸入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }
}

而後是解析得到的Content獲得想要的字段,題目,答案中的圖片連接python

package bean;

import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import mothed.Spider;

/**
 * 知乎圖片bean
 * @author ganhang
 *
 */
public class ZhiHuBean {
    public String zhihuUrl;// 網頁連接
    public String question;// 問題名;
    public ArrayList<String> zhihuPicUrl;// 圖片連接

    public String getQuestion() {
        return question;
    }

    public void setQuestion(String question) {
        this.question = question;
    }

    public ArrayList<String> getZhihuPicUrl() {
        return zhihuPicUrl;
    }

    public void setZhihuPicUrl(ArrayList<String> zhihuPicUrl) {
        this.zhihuPicUrl = zhihuPicUrl;
    }

    // 構造方法初始化數據
    public ZhiHuBean(String url) throws Exception {
        zhihuUrl = url;
        zhihuPicUrl = new ArrayList<String>();
        // 判斷url是否合法
        if (isZhuHuUrl(url)) {
            url=getRealUrl(url);
            System.out.println("正在抓取知乎連接:" + url);
            // 根據url獲取該問答的細節
            String content = Spider.GetContent(url);
            //System.out.println("content:"+content);
            Matcher m;
            // 匹配標題
            m = Pattern.compile("zh-question-title.+?<h2.+?>(.+?)</h2>").matcher(content);
            if (m.find()) {
                question = m.group(1);
            }
            // 匹配答案圖片連接
            m = Pattern.compile("</noscript><img.+?src=\"(https.+?)\".+?").matcher(content);
            boolean isFind;
            while (isFind= m.find()) {
                zhihuPicUrl.add(m.group(1));
            }
        }else throw new Exception("網址有誤!請輸入知乎網址!");
}

    // 處理url
    String getRealUrl(String url) {
        // 將http://www.zhihu.com/question/22355264/answer/21102139
        //轉化成http://www.zhihu.com/question/22355264
        Matcher m = Pattern.compile("(\\d*)/answer/(\\d*)").matcher(url);
        if (m.find()) {
            return "http://www.zhihu.com/question/" + m.group(1);
        } else {
            return url;
        }
    }
    //判斷知乎網址
    boolean isZhuHuUrl(String url){
        if(url.startsWith("http://www.zhihu.com/question/")){
            return true;
        }else return false;
    }
}

得到連接後就開始下載了正則表達式

 1 package mothed;
 2 
 3 import java.io.DataInputStream;
 4 import java.io.File;
 5 import java.io.FileOutputStream;
 6 import java.io.FileWriter;
 7 import java.io.IOException;
 8 import java.net.URL;
 9 import java.util.ArrayList;
10 
11 import bean.ZhiHuBean;
12 /**
13  * 下載器
14  * @author ganhang
15  *
16  */
17 public class DownLoad {
18     // 傳入zhiHuBean,建立文件夾,並下載圖片
19     public static boolean downLoadPics(ZhiHuBean zhiHuBean, String filePath) throws Exception {
20         // 文件路徑+標題
21         String dir = filePath + zhiHuBean.getQuestion();
22         // 建立
23         File fileDir = new File(dir);
24         fileDir.mkdirs();
25         // 獲取全部圖片路徑集合
26         ArrayList<String> zhiHuPics = zhiHuBean.getZhihuPicUrl();
27         // 初始化一個變量,用來顯示圖片編號
28         int i = 1;
29         // 循環下載圖片
30         for (String zhiHuPic : zhiHuPics) {
31             URL url = new URL(zhiHuPic);
32             // 打開網絡輸入流
33             DataInputStream dis = new DataInputStream(url.openStream());
34             String newImageName = dir + "/" + "圖片" + i + ".jpg";
35             // 創建一個新的文件
36             FileOutputStream fos = new FileOutputStream(new File(newImageName));
37             byte[] buffer = new byte[1024];
38             int length;
39             System.out.println("正在下載......第 " + i + "張圖片......請稍後");
40             // 開始寫入
41             while ((length = dis.read(buffer)) > 0) {
42                 fos.write(buffer, 0, length);
43             }
44             dis.close();
45             fos.close();
46             System.out.println("第 " + i + "張圖片下載完畢......");
47             i++;
48         }
49         return true;
50     }
51 }

測試類api

package test;

import java.util.ArrayList;

import mothed.DownLoad;
import bean.ZhiHuBean;


/**
 * 抓取知乎圖片並下載
 * 
 * @author ganhang
 *
 */
public class ZhiHuSpiderTest {

    public static void main(String[] args) throws Exception {
        /**
         * 爬知乎圖片,並下載到本地
         */
        // 連接注意用http
        String url = "http://www.zhihu.com/question/27621722";
        // 獲取ZhiHuBean
        ZhiHuBean myZhihu = new ZhiHuBean(url);
        // 獲取ZhiHuBean中的圖片列表
        ArrayList<String> picList = myZhihu.getZhihuPicUrl();
        // 打印結果
        System.out.println("標題:" + myZhihu.getQuestion());
        System.out.println("");
        //定義下載路徑
        String addr = "D:/知乎爬蟲/";
        System.out.println("即將開始下載圖片到"+addr+myZhihu.getQuestion());
        System.out.println("");
        System.out.println("開始下載................");
        System.out.println("");
        // 把圖片下載到本地文件夾
        DownLoad.downLoadPics(myZhihu, addr);
        System.out.println("");
        System.out.println("圖片下載完畢,請到"+addr+myZhihu.getQuestion()+"裏去看看吧!!!");

    }
}

打開文件夾就能夠慢慢欣賞圖片了。。網絡

相關文章
相關標籤/搜索