java項目開發實例「java爬蟲框架」

目標

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

收穫

通過本文,你將複習到:

  • IDEA創建工程
  • IDEA導入jar包
  • 爬蟲的基本原理
  • Jsoup的基本使用
  • File的基本使用
  • FileOutputStream的基本使用
  • ArrayList的基本使用
  • foreach的基本使用

說明

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

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

開始

一、前端分析

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

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

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

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

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

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

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

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

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

二、爬取思路

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

三、Java編碼

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

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

2、新建Java工程。

手把手教你從零開始用Java寫爬蟲
手把手教你從零開始用Java寫爬蟲
手把手教你從零開始用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("").get(); //這裡加鏈接
            System.out.println(doc);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
手把手教你從零開始用Java寫爬蟲

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

注意:鏈接沒給,否則文章審核不過,注意自己添加!!!

注意:鏈接沒給,否則文章審核不過,注意自己添加!!!
手把手教你從零開始用Java寫爬蟲

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

注意:鏈接沒給,否則文章審核不過,注意自己添加!!!

// 獲取response
Connection.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圖片,並且顯示正常!

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

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

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

//當前路徑下創建Pics文件夾
File file = new File("Pics");
file.mkdir();
System.out.println(file.getAbsolutePath());
手把手教你從零開始用Java寫爬蟲

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 ++;
}

運行結果

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

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

附錄一

Jsoup(HTML解析器)

繼承關係:Document繼承Element繼承Node。TextNode繼承Node。
->java.lang.Object
  ->org.jsoup.nodes.Node
    ->org.jsoup.nodes.Element
      ->org.jsoup.nodes.Document
html文檔: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();
        }
    }
}

原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/207543.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
投稿專員的頭像投稿專員
上一篇 2024-12-08 14:35
下一篇 2024-12-08 14:35

相關推薦

發表回復

登錄後才能評論