使用Java寫(xiě)一個(gè)簡(jiǎn)單爬蟲(chóng)爬取單頁(yè)面

使用Java爬蟲(chóng)爬取人民日?qǐng)?bào)公眾號(hào)頁(yè)面圖片

使用Java框架Jsoup和HttpClient實(shí)現(xiàn),先看代碼
爬取目標(biāo)頁(yè)面

1、使用Maven構(gòu)建一個(gè)普通Java工程

加入依賴:

        <!--用來(lái)解析Html頁(yè)面的第三方Jar-->
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.11.2</version>
        </dependency>
        <!--用來(lái)模擬Http客戶端的第三方Jar-->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.3.1</version>
        </dependency>

2、第一個(gè)類,開(kāi)始爬取入口類

package com.yomihu.spider;

import com.yomihu.parse.ParseHtml;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * mini-spider 單頁(yè)面爬取啟動(dòng)類
 *
 * @Author 孫龍
 * @Date 2018/1/28
 */
public class SinglePageSpiderStarter {
    /**
     * 開(kāi)始頁(yè)面的URL(一個(gè)微信公眾號(hào)的頁(yè)面)
     */
    private static final String START_URL = "https://mp.weixin.qq.com/s/zzkEWbcb81pbsr-PJvVzQA";
   /**
     * 目標(biāo)圖片存放目錄
     */
    private static final String IMG_SAVE_PATH = "E:/jj";

    public static void main(String[] args) throws Exception {
        //使用Jsoup將目標(biāo)Url的Html頁(yè)面獲取為Document變量
        Document rootdocument = Jsoup.connect(START_URL).get();

        List<String> urlList = new ArrayList<String>();
        //將頁(yè)面中的目標(biāo)Url解析為列表
        ParseHtml.singlePageParseImg(rootdocument, urlList);
        //初始化HttpClient對(duì)象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        //控制圖片名稱的變量
        int i = 0;
        for (String url : urlList) {
            HttpGet httpGet = new HttpGet(url);
            CloseableHttpResponse response = httpClient.execute(httpGet);

            InputStream inputStream = response.getEntity().getContent();
            //保存圖片
            File file = new File(IMG_SAVE_PATH);
            if (!file.exists()) {
                //不存在就創(chuàng)建該目錄
                file.mkdirs();
            }
            String imgName = IMG_SAVE_PATH + File.separator + "test" + i + ".jpg";
            //保存圖片
            FileOutputStream fos = new FileOutputStream(imgName);
            i++;
            byte[] data = new byte[1024];
            int len;
            while ((len = inputStream.read(data)) != -1) {
                fos.write(data, 0, len);
            }
            //釋放資源
            response.close();
        }
        httpClient.close();

    }
}

3、第二個(gè)類,解析Html頁(yè)面

package com.yomihu.parse;

import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.util.List;

/**
 * mini-spider Html頁(yè)面結(jié)構(gòu)解析
 *
 * @Author 孫龍
 * @Date 2018/1/28
 */
public class ParseHtml {

    /**
     * 微信單頁(yè)面結(jié)構(gòu)解析,這里我們只要將頁(yè)面中的圖片對(duì)應(yīng)的URL取出
     * (方法中的解析邏輯是根據(jù)分析頁(yè)面結(jié)構(gòu)和各元素的特征來(lái)解析的)
     *
     * @param document
     * @param urls
     */
    public static void singlePageParseImg(Document document, List<String> urls) {

        Elements divElements = document.select("[class=rich_media_content]");

        Elements pElements = divElements.select("p");
        Elements imgElements = pElements.select("img");
        for (Element imgElement : imgElements) {
            urls.add(imgElement.attr("data-src"));
             //打印目標(biāo)數(shù)據(jù),查看是否正確
        }
        Elements spanElements = pElements.select("span");

        Elements imgElemnets = spanElements.select("img");
        for (Element imgElement : imgElemnets) {
            urls.add(imgElement.attr("data-src"));
            //打印目標(biāo)數(shù)據(jù),查看是否正確
            System.out.println(imgElement.attr("data-src"));
        }
    }
}

4、啟動(dòng)第一個(gè)類中的main函數(shù)

查看我們爬取的目標(biāo)圖片是否已經(jīng)存在目錄中。

總結(jié)

其實(shí)爬蟲(chóng)并不難寫(xiě),首先要先知道爬蟲(chóng)是什么東西。爬蟲(chóng)就是使用程序模擬一個(gè)瀏覽器對(duì)頁(yè)面上的數(shù)據(jù)進(jìn)行不斷的連接獲取解析并保存;這里我只是使用Apache開(kāi)源的成熟框架進(jìn)行開(kāi)發(fā),實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的單頁(yè)面抓取,同樣的多頁(yè)面循環(huán)抓取就需要在程序中做不斷的迭代,并不斷的更新爬取目標(biāo);即在使用程序解析頁(yè)面的時(shí)候?qū)⑾乱粋€(gè)目標(biāo)頁(yè)的Url保存在待爬取的列表中。
爬蟲(chóng)并不難實(shí)現(xiàn),難的是對(duì)目標(biāo)頁(yè)面分析,找到頁(yè)面中個(gè)元素之間的規(guī)律,對(duì)頁(yè)面進(jìn)行規(guī)律性解析,并獲取到我們想要的數(shù)據(jù);當(dāng)然更難的是有些大網(wǎng)站服務(wù)器上的反爬蟲(chóng)機(jī)制。

接下來(lái)我會(huì)實(shí)現(xiàn)一個(gè)多頁(yè)面循環(huán)抓取的Demo
示例代碼

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,881評(píng)論 25 709
  • 于梁梁梁閱讀 155評(píng)論 0 0
  • 想寫(xiě)封信給你 說(shuō)‘秋天該很好 我喜歡這樣的秋 關(guān)于一個(gè)人的 還有一個(gè)人,依然有 很多人,很多人的秋天 破碎的記憶…...
    Mino_深海老怪物閱讀 199評(píng)論 0 1
  • 一 好吧。 嘆了口氣,醒來(lái)的時(shí)候,她努力揉了揉眼睛,然后凝視著周六窗外明媚的藍(lán)天,又重新回到兩眼無(wú)神地狀態(tài)掃視了一...
    張瀚允bling閱讀 259評(píng)論 0 2
  • 第二天 大清早就情緒低落。有什么事情是一碗米粉搞不定的,一碗搞不定,那就接連吃上幾天。。。 天氣真的很熱,風(fēng)也是熱...
    流頦閱讀 160評(píng)論 0 0

友情鏈接更多精彩內(nèi)容