手把手教你從零開始用Java寫爬蟲

    

本文將手把手地教大家從零開始用Java寫一個簡單地爬蟲!

 

目標

    爬取全景網圖片,並下載到本地

 

收穫

    通過本文,你將複習到:

  • IDEA創建工程

  • IDEA導入jar包

  • 爬蟲的基本原理

  • Jsoup的基本使用

  • File的基本使用

  • FileOutputStream的基本使用

  • ArrayList的基本使用

  • foreach的基本使用​

 

說明

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

    Jsoup相關API整理見文末附錄一。
 

開始

一、前端分析

1、使用Chrome或其他瀏覽器,打開全景網,按F12進入調試模式,分析網頁結構。(這裏選的是“創意”=>“優山美地”)

 

2、找規律,看圖片對應的結構是什麼。可以發現,每個圖片的結構都如下圖紅框所示。

 

3、找到結構後再找圖片鏈接。進一步分析後發現,圖片鏈接可以是下圖紅框部分。

 

4、複製到瀏覽器打開看看驗證下。(好吧,訪問這個URL直接給我下載了...)

 

5、前端部分分析完畢,接下來就可以用Java編碼了!

 

二、爬取思路

    通過Java向全景網發送GET請求,以獲取HTML文件。Jsoup解析後尋找class=item lazy的a標籤,他的child節點(即<img>)就是我們要找的目標節點了,搜索到的應當是一個ArrayList。然後遍歷集合,從中搜尋圖片的URL,並下載到本地保存。(更深一步,可以下載完一頁後,繼續下載後一頁,直至全部下完。本文直講下載第一頁。提示一下,鏈接後面的topic/1其實就是當前頁數)

 

三、Java編碼

1、先下載Jsoup jar包,並導入到IDEA工程中。

 

2、新建Java工程。

 

3、簡單測試下get請求,若請求成功,則進入下一步;若報錯,檢查URL是否帶了中文。

package com.sxf;import org.jsoup.Jsoup;import org.jsoup.nodes.Document;public class Main {    public static void main(String[] args) {        try {            Document doc = Jsoup.connect("https://www.quanjing.com/creative/topic/1").get();            System.out.println(doc);        }catch (Exception e){            e.printStackTrace();        }    }}

 

4、尋找class爲item lazy的元素,找到他的child節點,返回ArrayList。並將圖片的URL單獨提取出來。

public static void main(String[] args) {        try {            Document doc = Jsoup.connect("https://www.quanjing.com/creative/topic/1").get();            // 尋找class爲item lazy的元素,返回ArrayList。            Elements items = doc.getElementsByClass("item lazy");            ArrayList<String> URLS = new ArrayList<>();            for (Element i : items) {                // 將圖片的URL單獨提取出來。                URLS.add(i.child(0).attr("src"));            }            for (String str : URLS) {                System.out.println(str);            }        }catch (Exception e){            e.printStackTrace();        }    }

 

5、我們先嚐試用Jsoup下載一張圖片試試效果。

// 獲取responseConnection.Response imgRes = Jsoup.connect(URLS.get(0)).ignoreContentType(true).execute();FileOutputStream out = (new FileOutputStream(new java.io.File("demo.jpg")));// imgRes.body() 就是圖片數據out.write(imgRes.bodyAsBytes());out.close();

可以看到在當前工程路徑下,生成了demo.jpg圖片,並且顯示正常!

 

6、接下來,我們要創建一個文件夾,用來專門存放圖片。

    File相關API整理見文末附錄二。

//當前路徑下創建Pics文件夾File file = new File("Pics");file.mkdir();System.out.println(file.getAbsolutePath());

 

7、接下來開始遍歷圖片並下載。由於圖片較多,爲了簡單起見,我們保存圖片時候的名稱,就從1開始依次增吧。

// 遍歷圖片並下載int cnt = 1;for (String str : URLS) {    System.out.println(">> 正在下載:"+str);    // 獲取response    Connection.Response imgRes = Jsoup.connect(str).ignoreContentType(true).execute();    FileOutputStream out = (new FileOutputStream(new java.io.File(file, cnt+".jpg")));    // imgRes.body() 就是圖片數據    out.write(imgRes.bodyAsBytes());    out.close();    cnt ++;}

運行結果

 

到此編碼部分也結束了,完整代碼見文末附件三!

 

附錄一

Jsoup(HTML解析器)

繼承關係:Document繼承Element繼承Node。TextNode繼承Node。->java.lang.Object  ->org.jsoup.nodes.Node    ->org.jsoup.nodes.Element      ->org.jsoup.nodes.Documenthtml文檔:Document元素操作:Element節點操作:Node官方API:https://jsoup.org/apidocs/org/jsoup/nodes/Document.html  一、解析HTML並取其內容  Document doc = Jsoup.parse(html);二、解析一個body片斷  Document doc = Jsoup.parseBodyFragment(html);  Element body = doc.body();三、從一個URL加載一個Document  Document doc = Jsoup.connect("http://example.com")    .data("query", "Java")    .userAgent("Mozilla")    .cookie("auth", "token")    .timeout(3000)    .post();  String title = doc.title();四、從一個文件加載一個文檔  File input = new File("/tmp/input.html");  // baseUri 參數用於解決文件中URLs是相對路徑的問題。如果不需要可以傳入一個空的字符串  Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/");  五、使用DOM方法來遍歷一個文檔  1、查找元素  getElementById(String id)  getElementsByTag(String tag)  getElementsByClass(String className)  getElementsByAttribute(String key) // 和相關方法  // 元素同級  siblingElements()  firstElementSibling()  lastElementSibling()  nextElementSibling()  previousElementSibling()  // 關係  parent()  children()  child(int index)  2、元素數據  // 獲取屬性attr(String key, String value)設置屬性  attr(String key)  // 獲取所有屬性  attributes()  id()  className()  classNames()  // 獲取文本內容text(String value) 設置文本內容  text()  // 獲取元素內HTMLhtml(String value)設置元素內的HTML內容  html()  // 獲取元素外HTML內容  outerHtml()  // 獲取數據內容(例如:script和style標籤)  data()  tag()  tagName()  3、操作HTML和文本  append(String html)  prepend(String html)  appendText(String text)  prependText(String text)  appendElement(String tagName)  prependElement(String tagName)  html(String value)  六、使用選擇器語法來查找元素(類似於CSS或jquery的選擇器語法)  //帶有href屬性的a元素  Elements links = doc.select("a[href]");   //擴展名爲.png的圖片  Elements pngs = doc.select("img[src$=.png]");  //class等於masthead的div標籤  Element masthead = doc.select("div.masthead").first();   //在h3元素之後的a元素  Elements resultLinks = doc.select("h3.r > a"); 七、從元素抽取屬性、文本和HTML  1、要取得一個屬性的值,可以使用Node.attr(String key) 方法  2、對於一個元素中的文本,可以使用Element.text()方法  3、對於要取得元素或屬性中的HTML內容,可以使用Element.html(), 或 Node.outerHtml()方法  4、其他:    Element.id()    Element.tagName()    Element.className()    Element.hasClass(String className)

 

附錄二

File類

*java.io.File類用於表示文件或目錄。*創建File對象:// 文件/文件夾路徑對象File file = new File("E:/...");// 父目錄絕對路徑 + 子目錄名稱File file = new File("..." ,"");// 父目錄File對象 + 子目錄名稱  File file = new File("...","...");file.exists():判斷文件/文件夾是否存在file.delete():刪除文件/文件夾file.isDirectory():判讀是否爲目錄file.isFile():判讀是否爲文件夾file.mkdir():創建文件夾(僅限一級目錄)file.mkdirs():創建多及目錄文件夾(包括但不限一級目錄)file.createNewFile():創建文件file.getAbsolutePath():得到文件/文件夾的絕對路徑file.getName():得到文件/文件夾的名字file.String():同樣是得到文件/文件夾的絕對路徑等於file.getAbsolutePath()file.getParent():得到父目錄的絕對路徑

 

附錄三

完整代碼

package com.sxf;import org.jsoup.Connection;import org.jsoup.Jsoup;import org.jsoup.nodes.Document;import org.jsoup.nodes.Element;import org.jsoup.select.Elements;import java.io.File;import java.io.FileOutputStream;import java.util.ArrayList;public class Main {    public static void main(String[] args) {        try {            Document doc = Jsoup.connect("https://www.quanjing.com/creative/topic/1").get();            // 尋找class爲item lazy的元素,返回ArrayList。            Elements items = doc.getElementsByClass("item lazy");            ArrayList<String> URLS = new ArrayList<>();            // 將圖片的URL單獨提取出來。            for (Element i : items) {                URLS.add(i.child(0).attr("src"));            }            // 當前路徑下創建Pics文件夾            File file = new File("Pics");            file.mkdir();            String rootPath = file.getAbsolutePath();            System.out.println(">> 當前路徑:"+rootPath);            // 遍歷圖片並下載            int cnt = 1;            for (String str : URLS) {                System.out.println(">> 正在下載:"+str);                // 獲取response                Connection.Response imgRes = Jsoup.connect(str).ignoreContentType(true).execute();                FileOutputStream out = (new FileOutputStream(new java.io.File(file, cnt+".jpg")));                // imgRes.body() 就是圖片數據                out.write(imgRes.bodyAsBytes());                out.close();                cnt ++;            }        }catch (Exception e){            e.printStackTrace();        }    }}

 

 

 

喜歡的話,記得點看”哦~~↓↓↓

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章