Java爬取壁纸图片

news2024/9/22 13:35:32

Java爬取壁纸图片

  • 前言
  • 依赖
  • 爬取图片
    • 工具类 -- WallHavenDownloadToDir.java
  • 测试

前言

自己写了一个项目 想加一个功能:自动爬取壁纸发送给用户。说干就干,Python能干的,Java也能干!

参考文章:
jsoup的使用
Java爬虫爬取wallhaven的图片

依赖

这里使用Java爬取的话就要先引入一个依赖:jsoup,其中具体的方法可以看看上面我参考的文章,可以简单理解为一个用来处理HTML页面,并找出其中的元素的工具。

引入依赖

<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.15.1</version>
</dependency>

爬取图片

在这里我就爬取WallHaven上的图片了,当然要爬取其他的具体网站的图片就需要对需要爬取的界面做具体分析了。 遇到问题的话,就是访问太频繁的话,会被拒绝连接,建议爬取的时候每次爬取一张以后暂停几秒钟再去爬取

工具类 – WallHavenDownloadToDir.java

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.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Random;
import java.util.regex.Pattern;

/**
 * @Description 爬取图片的工具类
 * @Author 三文鱼先生
 * @Data 2023/5/6 11:42
 */
public class WallHavenDownloadToDir {

    /**
     * @Description 下载对应的图片地址到指定的目录下
     * @Param filePath 存储的文价目录
     * @Param imgUrl 下载的图片url
     * @Return {@link boolean} 是否下载成功
     * @Author 三文鱼先生
     * @Date 2023/5/9 14:58
     **/
    private static boolean downImages(String filePath, String imgUrl) {
        String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36";
        // 若指定文件夹没有,则先创建
        File dir = new File(filePath);
        if (!dir.exists()) {
            dir.mkdirs();
        }


        // 截取图片文件名
        String fileName = imgUrl.substring(imgUrl.lastIndexOf('/') + 1, imgUrl.length());

        try {
            // 文件名里面可能有中文或者空格,所以这里要进行处理。但空格又会被URLEncoder转义为加号
            String urlTail = URLEncoder.encode(fileName, "UTF-8");
            // 因此要将加号转化为UTF-8格式的%20
            imgUrl = imgUrl.substring(0, imgUrl.lastIndexOf('/') + 1) + urlTail.replaceAll("\\+", "\\%20");

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        // 写出的路径 如果已存在就不再下载
        File file = new File(filePath + File.separator + fileName);
        if(file.exists()) {
            System.out.println("该图片已下载。");
            return true;
        }

        try {
            //随机暂停几秒 太过频繁会被识别成爬虫 导致抓取不成功
            Thread.sleep(new Random().nextInt(3)*1000);
            //连接对应的url
            URL url = new URL(imgUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestProperty("User-agent", userAgent);//伪装报头
            connection.setConnectTimeout(20 * 1000);

            InputStream in = connection.getInputStream();
            System.out.println("图片大小为:" + in.available());
            BufferedOutputStream out = new BufferedOutputStream(
                    new FileOutputStream(file)
            );
            byte[] buf = new byte[1024];
            int size;
            while (-1 != (size = in.read(buf))) {
                out.write(buf, 0, size);
            }
            out.close();
            in.close();
            return true;
        } catch (IOException e) {
            System.out.println("下载图片时遇到未知错误。");
            return false;
        } catch (InterruptedException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @Description 根据对应的url 下载其中的所有图片
     * @Param filePath 保存的文件路劲
     * @Param url WallHaven对应的地址
     * @Return {@link boolean} 是否下载成功
     * @Author 三文鱼先生
     * @Date 2023/5/9 15:02
     **/
    private static boolean getImage(String filePath, String url) {
        //伪装的报头
        String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36";

        try {
            // 利用Jsoup获得连接
            Connection connect = Jsoup.connect(url)
                    .userAgent(userAgent);//伪装报头
            // 得到Document对象
            Document document = connect.get();
            // 查找所有img标签
            Elements imgs = document.getElementsByTag("a");
            String pattern = "https://wallhaven.cc/w/.*";
            //每次仅仅获取一个
            boolean result = false;
            // 遍历img标签并获得src的属性
            for (Element element : imgs) {
                //获取每个img标签URL "abs:"表示绝对路径
                String imgSrc = element.attr("abs:href");
                // 打印URL
                boolean isMatch = Pattern.matches(pattern, imgSrc);
                if (isMatch){
                    System.out.println("下载链接:"+imgSrc);
                    Connection con = Jsoup.connect(imgSrc)
                            .userAgent(userAgent)
                            .timeout(10*1000);//伪装报头;
                    Document doc = con.get();
                    Elements pic = doc.getElementsByTag("img");
                    System.out.println(pic);
                    System.out.println("开始下载");
                    for(Element p : pic)
                    {
                        Element picSrc = p.getElementById("wallpaper");
                        if(picSrc!=null)
                        {
                            String picsrc = picSrc.attr("abs:src");
                            System.out.println("图片链接:"+picsrc);
                            result = downImages(filePath, picsrc);
                            if(
                                    result
                            ) {
                                System.out.println("下载一张");
                            } else {
                                 //只要有一张下载不成功则重新来 但是已经下载的不会再进行下载
                                return false;
                            }
                        }
                    }
                }
            }
            return result;
        } catch (IOException e) {
            System.out.println("获取图片链接时遇到未知错误");
            return false;
        }
    }

    /**
     * @Description 循环一百次 直到爬取成功
     * @Param filePath 图片存储地址
     * @Param url WallHaven里面的对应搜索网址
     * @Return {@link boolean} 是否成功
     * @Author 三文鱼先生
     * @Date 2023/5/9 15:04
     **/
    public static boolean downloadImageWithUrl(String filePath,String url) {
        try {
            for (int i = 0; i < 100; i++) {
                //每个界面随机暂停五秒 防止太过频繁被识别成爬虫
                Thread.sleep(new Random().nextInt(5)*1000);
                //获取对应url的图片
                if(getImage(filePath ,url)) {
                    //下载成功则不再执行循环
                    break;
                }
            }
            return true;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return false;
    }
    
}

测试

根据自己的喜好去WallHaven里面筛选自己喜欢的类型图片,然后将对应的网址复制下来,作为上述工具类中的downloadImageWithUrl方法中的URL参数
在这里插入图片描述
如以下这样

WallHavenDownloadToDir.downloadImageWithUrl(storePath ,
                        "https://wallhaven.cc/toplist");
  

等待爬取结束即可。控制台会输出以下爬取信息

下载链接:https://wallhaven.cc/w/ex99o8
<img src="https://wallhaven.cc/images/layout/logo_sm.png" alt="wallhaven">
<img src="//wallhaven.cc/images/user/avatar/32/519198_046b6874f485.png" alt="jrmnt">
<img id="wallpaper" src="https://w.wallhaven.cc/full/ex/wallhaven-ex99o8.png" alt="General 1920x1080 digital art artwork illustration clouds city building skyscraper palm trees sunset sky trees sunset glow" data-wallpaper-id="ex99o8" data-wallpaper-width="1920" data-wallpaper-height="1080" crossorigin="anonymous">
共检测到下列图片URL:
开始下载
图片链接:https://w.wallhaven.cc/full/ex/wallhaven-ex99o8.png
图片大小为:15636
下载一张

再进自己设置的存储目录看下,没什么问题了

在这里插入图片描述
当然有时候会拒绝连接好几次,显示获取图片时出错,等一会就好了,一般是会被拒绝二十来次。但是不要担心,循环里设置的是100次基本都会成功。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/506203.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STL-Vector容器

vector数据结构和数组非常相似&#xff0c;也称为单端数组 vector与普通数组区别&#xff1a; 数组是静态空间&#xff0c;而vector可以动态扩展 vector容器的迭代器是支持随机访问的迭代器 目录 创建vector容器 vector 容器赋值 vector容器的大小 vector插入和删除 ve…

java计算矩形的面积和周长的方法

在生活中&#xff0c;我们常常需要计算某个矩形的面积和周长&#xff0c;如我们经常用的计算器就是个不错的选择&#xff0c;它可以计算出任意一个矩形的面积和周长。那么&#xff0c;如果你想使用 Java编程语言来计算矩形的面积和周长&#xff0c;你该如何做呢&#xff1f;今天…

基于WiFi做呼吸频率检测-python版

一、概述 本Demo无需机器学习模型&#xff0c;Demo功能涉及的理论主要参考了硕士学位论文《基于WiFi的人体行为感知技术研究》&#xff0c;作者是南京邮电大学的朱XX&#xff0c;本人用python复现了论文中呼吸频率检测的功能。Demo实现呼吸速率检测的主要过程为&#xff1a; …

C# 对PdfiumViewer工具栏进行自定义,实现放大缩小,首页, 尾页,上一页等功能。

文章目录 前言PdfiumViewer工具栏扩展1 创建winform工程&#xff0c;UI界面2 打印预览3 放大功能4 缩小功能5 按比例缩放6 全屏7 首页和尾页8 上一页和下一页9 页码输入框10 显示当前预览的页码 小结 前言 关于PdfiumViewer的介绍 C# 使用PdfiumViewer实现对PDF文档打印预览&a…

【论文学习】ECAPA-TDNN: Emphasized Channel Attention, Propagation and Aggregation

ECAPA-TDNN: Emphasized Channel Attention, Propagation and Aggregation 目录 ECAPA-TDNN: Emphasized Channel Attention, Propagation and Aggregation摘要1 介绍2 DNN说话人识别系统2.1 Extended-TDNN x-vector2.2 基于ResNet的r-vector 3 提出的ECAPA-TDNN架构3.1 依赖于…

【Unity之c#专题篇】—核心章题单实践

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

电脑开关机-第14届蓝桥杯省赛Scratch初级组真题第1题

[导读]&#xff1a;超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成&#xff0c;后续会不定期解读蓝桥杯真题&#xff0c;这是Scratch蓝桥杯真题解析第130讲。 电脑开关机&#xff0c;本题是2023年5月7日举行的第14届蓝桥杯省赛Scratch图形化编程初级组真题第1题&#…

flstudio21有什么新功能,主题随心换,苹果M2/1家族芯片原生支持

FL Studio 21推出 – 新功能和改进。如果您从事音乐制作&#xff0c;那么您不可能没有听说过 FL Studio&#xff0c;或者很可能已经使用过这个音乐程序。好了&#xff0c;新版本的 FL Studio 21 DAW已经准备好向公众发布了。Image-line 正在为 2023 年的大型揭幕准备最终细节。…

go 源码解读 - sync.WaitGroup

go version 1.19.7 在 Go 语言中&#xff0c;sync.WaitGroup 是一个并发编程的同步工具&#xff0c;用于等待一组 Goroutine 执行完毕。 当需要等待多个 Goroutine 完成任务后才能执行下一步操作时&#xff0c;我们可以使用 sync.WaitGroup 实现协程间的同步。它提供了 Add()…

测试:概念篇

目录 简单介绍测试 我们先简单的介绍一下测试工程师 简单来看看测试和开发的区别 测试的基本概念 什么是需求 BUG 的概念 测试用例 什么是测试用例&#xff1f; 为什么有测试用例 测试周期 开发模型 瀑布模型&#xff1a; 螺旋模型&#xff1a; 敏捷软件开发 V …

PostgreSQL 查找重复数据(二)

创建表和测试数据&#xff1a; -- DROP TABLE IF EXISTS people; CREATE TABLE people (id integer GENERATED ALWAYS AS IDENTITY PRIMARY KEY,name varchar(50) NOT NULL,email varchar(100) NOT NULL );INSERT INTO people(name, email) VALUES (张三, zhangsantest.com),(李…

操作系统考试复习-—第四章 分段式 段页式存储方式

分段从存储管理方式&#xff1a;一方面是通常的程序都可以分为若干段&#xff0c;另一方面是实现和满足信息共享&#xff0c;信息保护&#xff0c;动态链接以及信息的动态增长等需要。也都是以段为基本单位实现的。所以说&#xff0c;分段存储管理方式更符合用户和程序员多方面…

JWT认证

一、什么是JWT 官网地址: https://jwt.io/introduction/ jsonwebtoken&#xff08;JWT&#xff09;是一个开放标准&#xff08;rfc7519&#xff09;&#xff0c;它定义了一种紧凑的、自包含的方式&#xff0c;用于在各方之间以JSON对象安全地传输信息。此信息可以验证和信任&…

华为nqa实验拓扑案例

bqa是一种实时的网络性能探测和统计技术&#xff0c;可以对响应时间、网络抖动、丢包率等网络信息进行统计。如图1所示&#xff0c;接口备份与NQA联动功能配置相对简单&#xff0c;只需在本端RouterA上配置NQA测试例&#xff0c;并在RouterA的备份接口上配置接口备份与NQA联动&…

自定义组件中如何注入Spring底层的组件

1.概述 自定义的组件要想使用Spring容器底层的一些组件&#xff0c;比如ApplicationContext&#xff08;IOC容器&#xff09;、底层的BeanFactory等等&#xff0c;那么只需要让自定义组件实现XxxAware接口即可。此时&#xff0c;Spring在创建对象的时候&#xff0c;会调用XxxA…

搞懂 API,API 常见技术使用场景分享

API&#xff08;应用程序编程接口&#xff09;是一种允许软件应用程序之间相互交互和通信的技术。以下是API常用的使用场景&#xff1a; 应用程序开发 API通常被用于网站或应用程序的开发中&#xff0c;以便在不同平台、语言及数据库之间获取数据或进行消息传递。例如&#xff…

探索数字化转型新道路!流辰信息微服务与您一起创未来!

科技在进步&#xff0c;社会在发展&#xff0c;办公自动化也在高速发展中。数字化转型是当下企业获得长久发展的趋势之一&#xff0c;在信息瞬间万变的社会中&#xff0c;谁掌握了核心技术&#xff0c;谁能与时代同步&#xff0c;谁就能开启新的康庄大道&#xff0c;谁就能在转…

VS2017配置Qt——超详细步骤教学(看完不会算你狠)

一、环境要求 visual studio 2017 vsaddin Qt14.1 mysql 注意mysql环境与msvc2017编译器环境保持一致。 mysql32位 配 msvc2017 32位 或 mysql64位 配 msvc2017 64位 注意&#xff1a;环境不一致会导致软件运行错误&#xff0c;为了避免这些错误&#xff0c;要将…

第1章计算机系统漫游之 “源代码的编译与执行” 及 “操作系统管理硬件”

文章目录 1、信息就是位上下文2、程序被其他程序翻译成不同的格式3、了解编译系统如何工作的益处4、处理器读并解释储存在存储器中的指令4.1 系统的硬件组成4.2 执行 hello 程序 5、高速缓存6、形成层次结构的存储设备7、操作系统管理硬件7.1 进程7.2 线程7.3 虚拟存储器7.4 文…

docker容器内使用cat命令修改文件

有时候docker容器内部没装vi 或vim命令&#xff0c;无法使用vi来修改文件 可以使用cat命令来查看文件 cat 主要功能一次显示整个文件:cat filename 从键盘创建一个文件:cat > filename 只能创建新文件,不能编辑已有文件 将几个文件合并为一个文件:cat file1 file2 > fi…