Jsoup - 【Java爬虫】- 批量下载指定网站图片

简介

Jsoup 是一款Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的API,可通过 DOM,CSS 以及类似于 JQuery 的操作方法来取出和操作数据。

Jsoup 对多线程、连接池、代理等等的支持并不是很好,所以一般把 Jsoup 仅仅作为 HTML 解析工具使用。

  • 功能

    • 从一个 URL、文件或字符串中解析 HTML

    • 使用 DOM 或 CSS 选择器来查找、取出数据

    • 可操作 HTML 元素、属性、文本

  • 引入依赖

     
     
         org.jsoup
         jsoup
         1.15.3
     
  • 解析 URL

     /**
      * 方式一:
      */
     public void jsoupTest() throws IOException {
         /**
          * 参数:
          *  1、url地址
          *  2、超时时间
          */
         Document document = Jsoup.parse(new URL("http://www.xxx.com"),10000);
         // 使用标签选择器获取指定标签中的内容
         // 获取第一个 title 标签元素的文本内容
         String title = document.getElementsByTag("title").first().text();
     }
     /**
      * 方式二:
      */
     public void jsoupTest() throws IOException {
         // 连接到指定网站
         Connection connection = Jsoup.connect("http://www.xxx.com");
         // 获取网站页面上所有的 DOM 元素
         Document document = connection.get();
     }
  • 使用 DOM 方式遍历文档

    • 元素获取

      • 根据 ID 查询元素:getElementById

      • 根据 标签 查询元素:getElementByTag

      • 根据 Class 查询元素:getElementByClass

      • 根据 属性 查询元素 getElementByAttribute

    •  Element byId = document.getElementById("qxzxqm");
       Elements byTag = document.getElementsByTag("img");
       Elements byClass = document.getElementsByClass("schoolcon_right");
       Elements byAttribute = document.getElementsByAttribute("rel");
    • 使用 Jsoup API 获取元素

      • select()

      • first()

      • get()

      • attr()

      • ......

在线 API:Jsoup (jsoup 1.6.3 API)

示例:爬取网站图片

 import org.jsoup.Connection;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.select.Elements;
 import utils.PrintLogThread;
 ​
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.List;
 ​
 /**
  * 爬取指定网址上的图片
  *
  * Tips:
  * 若出现 403 错误则可能是由于“写入”访问被禁止而造成的
  * 当试图将文件上载到目录或在目录中修改文件,但该目录不允许"写"访问时就会出现此种错误
  *
  * @author 秋玄
  * @version 1.0
  * @since 1.0
  */
 public class App {
     public static void main(String[] args) {
         // 网站地址
         String site = "https://xxx.xxx.com/";
         // 图片保存路径
         String filePath = "F://test";
         // 自定义图片名称
         String fileName = "img";
         downloadImg(site,filePath,fileName);
     }
 ​
     /**
      * 获取指定网站上所有图片
      * @param website       指定网站的完整域名 包括请求协议,例如:www.xxx.com
      * @param filePath      图片存放路径 例如:F://test
      * @param fileName      图片名称 例如:xxx
      */
     private static void downloadImg(String website,String filePath,String fileName) {
         List urlList = new ArrayList<>();
         try {
             // 获取网站图片的 src
             // 连接到指定网站
             Connection connection = Jsoup.connect(website);
             // 获取网站页面上所有的 DOM 元素
             Document document = connection.get();
             // 获取所有的 img 元素
             Elements imgs = document.getElementsByTag("img");
             // 遍历 imgs
             for (int i = 0; i < imgs.size(); i++) {
                 // 获取 img 元素的 src 属性
                 String src = imgs.get(i).attr("src");
 ​
                 // url地址以 “//” 开始,需要拼接请求协议
                 if (src.startsWith("//")){
                     src = "http:" + src;
                 }
 ​
                 // 路径为 空 或 “about:blank” 则不添加到 List 中
                 if (src.length() != 0 && !"about:blank".equals(src)) {
                     urlList.add(src);
                 }
 ​
                 // 下载图片
                 getImg(urlList,filePath,fileName);
 ​
                 // 记录日志到 log.txt 文件
                 PrintLogThread thread = new PrintLogThread("下载完成,第" + (i + 1) + "张图片",filePath + "//log.txt");
                 thread.start();
             }
         } catch (IOException e) {
             throw new RuntimeException(e);
         }
     }
 ​
     /**
      * 下载指定 URL 的图片
      * @param imgURL        图片地址的 list 集合
      * @param filePath      图片存放路径
      * @param fileName      图片文件名称
      */
     private static void getImg(List imgURL,String filePath,String fileName){
         InputStream in = null;
         FileOutputStream fos = null;
 ​
         // 遍历图片地址 list 集合
         for (int i = 0; i < imgURL.size(); i++) {
             try {
                 URL url = new URL(imgURL.get(i));
                 in = url.openStream();
 ​
                 // 拼接文件存放路径及文件名
                 String path = appendPath(filePath,fileName,i);
 ​
                 // 将图片写入本地
                 fos = new FileOutputStream(path);
                 byte[] bytes = new byte[1024];
                 int count = in.read(bytes);
                 while(count != -1){
                     fos.write(bytes,0,count);
                     fos.flush();
                     count = in.read(bytes);
                 }
             } catch (IOException e) {
                 throw new RuntimeException(e);
             }finally {
                 // 释放资源
                 if (in != null) {
                     try {
                         in.close();
                     } catch (IOException e) {
                         throw new RuntimeException(e);
                     }
                 }
                 if (fos != null) {
                     try {
                         fos.close();
                     } catch (IOException e) {
                         throw new RuntimeException(e);
                     }
                 }
             }
         }
     }
 ​
     /**
      * 拼接文件存放路径及文件名
      * @param filePath      文件路径
      * @param fileName      文件名
      * @param i             文件编号
      * @return              文件完整路径
      * 格式:文件路径 + 文件名称 + _ + 文件编号 + 文件后缀(.jpg)
      */
     private static String appendPath(String filePath,String fileName,Integer i) {
         return filePath + "//" + fileName + "_" + (i + 1) + ".jpg";
     }
 }
package utils;
 ​
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.PrintStream;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 ​
 /**
  * 日志工具类 - 记录日志
  *
  * @author 秋玄
  * @version 1.0.0
  * @since 1.0.0
  */
 public class LoggerUtil {
     /**
      * 记录日志
      * @param msg           需要记录的信息
      * @param filePath      日志文件的路径
      */
     public static void log(String msg,String filePath){
         try {
             // 指定一个日志文件
             PrintStream printStream = new PrintStream(new FileOutputStream(filePath,true));
 ​
             // 改变输出方向
             System.setOut(printStream);
 ​
             // 日期调用方法时的当前时间
             Date now = new Date();
             SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
             String strTime = sdf.format(now);
 ​
             // 输出日志信息到日志文件
             System.out.println(strTime + " : " + msg);
 ​
         } catch (FileNotFoundException e) {
             throw new RuntimeException(e);
         }
     }
 }
 package utils;
 ​
 public class PrintLogThread extends Thread{
     private String msg;
     private String filePath;
 ​
     private PrintLogThread(){}
 ​
     public PrintLogThread(String msg,String filePath){
         this.msg = msg;
         this.filePath = filePath;
     }
 ​
     @Override
     public void run() {
         LoggerUtil logger = new LoggerUtil();
         logger.log(msg,filePath);
     }
 }

 
     4.0.0
 ​
     org.example
     JavaCrawler
     1.0-SNAPSHOT
 ​
     
         8
         8
     
 ​
     
         
         
             org.jsoup
             jsoup
             1.14.3
         
     
 ​
 

一  叶  知  秋,奥  妙  玄  心

你可能感兴趣的:(Java,java)