自建背景图库

平时一些软件需要用到背景图片,但是一直用一张背景图片时间长了又会觉得腻,所以一直使用的都是随机图片来作为背景,之前用的那个接口最近一段时间晚高峰的时候总会响应很慢,所以自建了一个图库,这样可以更好的留存自己喜欢的图片

实现思路

  1. 批量爬取一部分图片
  2. 把图片放置到自定义的web静态文件路径下
  3. 获取所有图片的路径、拼接url路径并上传到数据库
  4. 写一个接口实现获取数据库中所有数据的数量,并使用random方法随机返回一个值作为ID从数据库中查询出对应的url重定向

使用依赖

<!--mysql数据库驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--hutool工具类-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.7.15</version>
        </dependency>
        <dependency>
            <!-- jsoup HTML parser library @ https://jsoup.org/ -->
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.14.3</version>
        </dependency>

爬取图片

图片地址:https://mm.tvv.tw/category/Innocent_girl/1/

DOM分析

打开https://mm.tvv.tw/category/Innocent_girl/1/

  1. 通过浏览器打开https://mm.tvv.tw/category/Innocent_girl/1/发现每一组图片都有一个对应的class属性blog-image

image-20220210132609728

  1. 我们可以根据class属性获取到所有的套图集合
  2. 同时每一个套图都有一个对应的<a>标签,标签中的href属性就是我们需要的套图的url

打开获取到的套图url

  1. 通过浏览器审查元素可以看到所有的图片都在一个class属性为blog-details-text的下面
  2. 但是又发现blog-details-text下面还有<p>标签环绕
  3. 此时我们可以用select来获取p:nth-child(2) > img所有的img集合
  4. 通过获取到的图片url集合遍历请求并保存到本地

image-20220210133151084

实现代码

package cc.wuque.tool.reptile;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Objects;

/**
 * @author 无缺
 * @ClassName mm_tvv_twReptile
 * @date 2022/2/9 18:29
 * @Description https://mm.tvv.tw/category/Innocent_girl网站图片爬取
 */
public class mm_tvv_twReptile {

    private static final Log log = LogFactory.get();
    private static final String FILE_PATH = "./file/";

    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        for (int i = 1; i < 15; i++) {
            String body = HttpRequest.get("https://mm.tvv.tw/category/Innocent_girl/" + i + "/").execute().body();
            Elements elements = Jsoup.parse(body).getElementsByClass("blog-image");
            log.info("当前链接:https://mm.tvv.tw/category/Innocent_girl/{}/共获取到{}个元素", i, elements.size());
            for (Element element : elements) {
                //"#features > div > div.row.blog-masonry.blog-masonry-4col.no-transition > div:nth-child(" + j + ") > div.blog-image > a"
                String href = element.select("a").attr("href");
                log.info("当前获取到的链接:{}", href);
                list.add(href);
            }
        }
        log.info("共获取到:{}个图片主题链接", list.size());
        for (String s : list) {
            String body = HttpRequest.get(s).execute().body();
            Document parse = Jsoup.parse(body);
            Elements elements = parse.getElementsByClass("blog-details-text").select("p:nth-child(2)").select("img");
            String title = Objects.requireNonNull(parse.getElementsByClass("blog-details-headline text-black").first()).text();

            log.info("当前链接:{},共获取到{}张图片", s, elements.size());
            for (Element element : elements) {
                String src = element.attr("src");
                log.info("当前图片链接:{}", src);
                InputStream inputStream = HttpRequest.get(src).execute().bodyStream();
                FileUtil.writeFromStream(inputStream, FILE_PATH + title + "/" + RandomUtil.randomString(12) + ".jpg");
            }
            //body > section > div > div > div.col-md-8.col-sm-8 > div.blog-details-text > p:nth-child(2) > img:nth-child(1)
        }
    }

}

创建数据库

CREATE TABLE `wuqueapi_random_image` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `url` varchar(255) NOT NULL,
  `path` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1723 DEFAULT CHARSET=utf8;

DBUtil工具类

package cc.wuque.tool.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ResourceBundle;


public class DBUtil {

    //数据库驱动
    private static final String driverClass = "com.mysql.jdbc.Driver";
    //数据库地址
    private static final String url = "jdbc:mysql://127.0.0.1:3306";
    //数据库用户名
    private static final String username = "root";
    //数据库密码
    private static final String password = "123456";


    static {
        try {
            //注册驱动
            Class.forName(driverClass);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url, username, password);
    }
}

这里的数据库地址、用户名、密码请修改成自己的

上传图片的路径和url到数据库

package cc.wuque.tool.file;

import cc.wuque.tool.util.DBUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;

import java.io.File;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;

/**
 * @author 无缺
 * @ClassName FileInfo
 * @date 2022/2/9 20:16
 * @Description 遍历当前目录下的所有文件地址,并上传到数据库
 */
public class FileInfo {
    private static Connection conn = null;
    private static PreparedStatement ps = null;
    private static final Log log = LogFactory.get();

    public static void main(String[] args) {
        //获取所有图片的路径并保存到list集合
        List<File> files = FileUtil.loopFiles("E:\\Java\\IdeaProject\\tool\\target\\classes\\file");
        //遍历集合
        for (File file : files) {
            //获取文件路径
            String path = file.getAbsolutePath();
            //截取并拼接路径
            path = "random/images" + path.substring(path.indexOf("file\\") + 4);
            log.info(path);
            //替换路径中的\为/
            path = path.replaceAll("\\\\", "/");
            //拼接url
            String url = "https://img.wuque.cc/" + path;
            try {
                //上传到数据库
                conn = DBUtil.getConnection();
                ps = conn.prepareStatement("insert into wuqueapi.wuqueapi_random_image(url,path) values(?,?)");
                ps.setString(1, url);
                ps.setString(2, path);
                ps.executeUpdate();
            } catch (SQLException e) {
                e.printStackTrace();
                log.error("数据库链接错误,请排查错误....");
            } finally {
                try {
                    //关闭驱动
                    conn.close();
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }

            }
        }
    }
}

实现随机返回图片api接口

package cc.wuque.api.controller;

import cc.wuque.api.bean.RandomImages;
import cc.wuque.api.service.RandomImagesService;
import cn.hutool.core.net.url.UrlBuilder;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * @author 无缺
 * @date 2022/2/9 21:09
 */
@Controller
public class randomImagesController {

    private static final Log log = LogFactory.get();
    private static int count;

    @Autowired
    private RandomImagesService randomImages;

    /**
     * 随机重定向返回一张图片
     *
     * @param response
     */
    @GetMapping(value = "/random/images")
    public void randomImagesRedirect(HttpServletResponse response) {
        if (count == 0) {
            getRandomImagesCount();
        }
        int i = RandomUtil.randomInt(0, count);
        String url = randomImages.queryRandomImagesById(i).getUrl();
        log.info("{}", url);
        try {

            response.sendRedirect(UrlBuilder.ofHttp(url).build());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取数据库中所有图片的集合
     */
    private void getRandomImagesCount() {
        List<RandomImages> imagesList = randomImages.queryAllRandomImages();
        log.info("执行了获取所有数据的方法....");
        count = imagesList.size();
    }

}

api接口中的service和mapper方法请自行实现..

最后修改:2022 年 02 月 10 日 01 : 54 PM
如果觉得我的文章对你有用,请随意赞赏