Java爬虫爬取图片壁纸

Java爬虫

Java爬虫爬取图片壁纸_第1张图片

sougou图片为例:https://pic.sogou.com/

JDK17、SpringBoot3.2.X、hutool5.8.24实现Java爬虫,爬取页面图片

项目介绍

开发工具:IDEA2023.2.5

JDK:Java17

SpringBoot:3.2.x

通过 SpringBoot 快速构建开发环境,通过 Jsoup 实现对网页的解析,并获取想要的资源数据

使用 hutool 工具,将所需要的字符串转成 JSON 对象,并从 JSON 对象中获取对应的数据资源

爬取网页图片资源,并将爬取到的资源下载到本地文件夹,对于大量的资源使用多线程下载

核心Jar包


<dependency>
    <groupId>org.jsoupgroupId>
    <artifactId>jsoupartifactId>
    <version>1.15.3version>
dependency>

项目依赖

pom.xml


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>
    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>3.2.1version>
        <relativePath/>
    parent>

    <groupId>cn.molugroupId>
    <artifactId>jsoupartifactId>
    <version>0.0.1-SNAPSHOTversion>
    <name>jsoupname>
    <description>
        java网络爬虫;更多技术分享地址请关注:https://blog.csdn.net/qq_51076413
    description>

    <properties>
        <java.version>17java.version>
        <java.source.version>17java.source.version>
        <java.target.version>17java.target.version>
        <java.compiler.version>17java.compiler.version>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
    properties>
    <dependencies>
        
        <dependency>
            <groupId>cn.hutoolgroupId>
            <artifactId>hutool-allartifactId>
            <version>5.8.24version>
        dependency>
        
        <dependency>
            <groupId>org.jsoupgroupId>
            <artifactId>jsoupartifactId>
            <version>1.15.3version>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-devtoolsartifactId>
            <scope>runtimescope>
            <optional>trueoptional>
        dependency>
        
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
        dependency>
    dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombokgroupId>
                            <artifactId>lombokartifactId>
                        exclude>
                    excludes>
                configuration>
            plugin>
        plugins>·
    build>
project>

爬取思路

一、解析网页:获取资源网页,从网页中解析想要的资源数据;

  • 查看网页资源的位置,分析资源渲染到页面的规律;
  • 根据分析到的规律,统一提取资源数据,得到列表;
  • 对列表数据进行进一步解析,最终拿到想要的资源;
  • 对资源数据进行处理,保存到数据库或是下载资源;

二、调用接口:直接获取想要的图片资源;

  • 需要分析资源网站,获取资源数据加载的时机和请求接口;
  • 分析接口的请求参数,入参是否有加密,是否有请求限制;
  • 测试接口,拿到结果,查看结果是否是自己所需要的资源;
  • 处理资源数据,保存到数据库或者将资源文件下载到本地;

三、缓存资源:从页面JS中直接获取资源

  • 页面加载后,我们下滑或者分页时,没有请求日志;
  • 页面没有重新加载,但是数据在不断更新和加载中;
  • 当超过一定数量时,会有一次的请求日志显示出来;
  • 最后分析得到,数据是缓存到页面中的JS变量中了;

一、解析网页

1.1、过程与思路

分析资源:

  • 打开资源网站,分析和定位资源所在位置,并分析资源渲染到页面的规律;
  • 如图,定位到资源位置,并发现了资源渲染的规律,使用document.querySelectorAll('xxx')可以得到页面中所有的资源
    网站地址:https://pic.sogou.com/pic/searchList.jsp?from=homeHotSearch&rcer=&spver=0&keyword=美女壁纸#top=1395.199951171875&more=false

定位资源所在位置
Java爬虫爬取图片壁纸_第2张图片

使用css选择器获取资源:

  • 根据分析到的规律,统一提取资源数据,得到列表;
  • document.querySelectorAll('div#result div.similar div.similar-item a.single-box') 得到所有的资源列表

Java爬虫爬取图片壁纸_第3张图片

获取资源链接和标题:

  • 对列表数据进行进一步解析,最终拿到想要的资源;
  • document.querySelector('xxx')提取资源标题和资源链接

Java爬虫爬取图片壁纸_第4张图片

示例代码如下:

let divElement = document.querySelectorAll('div#result div.similar div.similar-item a.single-box'), result = [];
for (let tag of divElement ) {
    let title = (tag.querySelector('h4.info-title').innerText||'').replace(/\s*/g,''); // 拿到标题,去除所有空格和特殊字符
    let url = tag.querySelector("div.img-height img").currentSrc||''; // 拿到资源链接
    result.push({title,url}); // 收集资源数据
}
console.log(result); // 打印资源列表

处理资源数据:

  • 对资源数据进行处理,保存到数据库或是下载资源;

1.2、Java代码实现

按照以上思路,我们使用Java代码来实现以上操作;

页面地址:https://pic.sogou.com/pic/searchList.jsp?from=homeHotSearch&rcer=&spver=0&keyword=美女壁纸#top=1395.199951171875&more=false

public static void main(String[] args) {
    // 获取网页资源
    Document document = Jsoup.parse(HttpUtil.get("https://pic.sogou.com/pic/searchList.jsp?from=homeHotSearch&rcer=&spver=0&keyword=美女壁纸#top=1395.199951171875&more=false", 15000));
    // 只获取标签中的元素
    Element body = document.body();
    // 使用css选择器提取所有资源,得到列表数据
    Elements aElements = Optional.of(body.select("div#result"))
        .orElseGet(Elements::new).select("div.similar div.similar-item a.single-box");
    // 进一步解析,获取资源链接和标题,将资源收集成集合中
    Set<JSONObject> result = aElements.stream().map(tag -> {
        JSONObject resource = new JSONObject();
        String title = tag.select("div.img-info h4.info-title").text();
        String src = tag.select("div.img-height img").attr("src");
        return resource.set("title", title).set("src", src);
    }).filter(ObjUtil::isNotEmpty).collect(Collectors.toSet());
    // 打印数据集
    System.out.println(result);
    System.out.println("共获取到:" + result.size() + "条数据");
}

1.3、爬取结果展示

[{"title":"每日更新 颜值美女壁纸,男人看了都会 珍藏 颜值","src":"https://i04piccdn.sogoucdn.com/485013ec7340e4f6"}, 
{"title":"美女 手机壁纸","src":"https://i02piccdn.sogoucdn.com/25a5aad0f9df1e0f"}, 
{"title":"美女 手机壁纸","src":"https://i04piccdn.sogoucdn.com/d4fe1d8d67d92d03"}, 
{"title":"美女 手机壁纸","src":"https://i01piccdn.sogoucdn.com/c9363d03d43130cd"}, 
{"title":"亭亭玉立,美若天仙","src":"https://i04piccdn.sogoucdn.com/51ea6e33666f6e57"}]

共获取到:5条数据

二、调用接口

2.1、过程与思路

分析网站资源得到资源接口:

  • 需要分析资源网站,获取资源数据加载的时机和请求接口;
  • 分析接口的请求参数,入参是否有加密,是否有请求限制;
  • 测试接口,拿到结果,查看结果是否是自己所需要的资源;
  • 处理资源数据,保存到数据库或者将资源文件下载到本地;

Java爬虫爬取图片壁纸_第5张图片

2.2、Java代码实现

按照上述,找到接口https://pic.sogou.com/napi/wap/searchlist,拿到参数,直接发起POST请求,得到资源;

请求参数

{
    "initQuery": "美女手机壁纸", 
    "queryFrom": "wap",
    "from": "homeHotSearch",
    "rcer": "",
    "spver": "0",
    "keyword": "美女壁纸",
    "start": 48,
    "reqType": "client",
    "reqFrom": "wap_result",
    "prevIsRedis": "n",
    "qua": "",
    "headers": {},
    "pagetype": 0,
    "amsParams": []
}

Java代码

接口地址:https://pic.sogou.com/napi/wap/searchlist

请求方式:POST

public static void main(String[] args) {
    // 查询接口
    String postUrl = "https://pic.sogou.com/napi/wap/searchlist";
    // 查询参数
    String params = """
                {
                    "initQuery": "美女手机壁纸",
                    "queryFrom": "wap",
                    "from": "homeHotSearch",
                    "rcer": "",
                    "spver": "0",
                    "keyword": "美女壁纸",
                    "start": 48,
                    "reqType": "client",
                    "reqFrom": "wap_result",
                    "prevIsRedis": "n",
                    "qua": "",
                    "headers": {},
                    "pagetype": 0,
                    "amsParams": []
                }
                """;
    // 发起post请求,得到上图所述的结果数据
    String json = HttpUtil.post(postUrl, params, 15000);
	// 解析结果数据,拿到最终的资源节点
    JSONArray jsonArray = JSONUtil.parseObj(json).getJSONObject("data").getJSONObject("picResult").getJSONArray("items");
	// 进一步解析提取所需要的资源数据,排除不需要的数据,将资源收集成集合中
    Set<JSONObject> result = jsonArray.stream().map(item -> {
        JSONObject resource = new JSONObject();
        if (item instanceof JSONObject jsonObject) {
            String title = jsonObject.getStr("title"); // 资源标题
            String picUrl = jsonObject.getStr("picUrl"); // 图片链接
            String thumbUrl = jsonObject.getStr("thumbUrl"); // 缩略图链接
            String oriPicUrl = jsonObject.getStr("oriPicUrl"); // 原图链接
            String locImageLink = jsonObject.getStr("locImageLink"); // 原图链接
            return resource.set("title", title).set("picUrl", picUrl)
                .set("thumbUrl", thumbUrl).set("oriPicUrl", oriPicUrl)
                .set("locImageLink", locImageLink);
        }
        return null;
    }).filter(ObjUtil::isNotEmpty).collect(Collectors.toSet());
    // 打印数据集
    System.out.println(result);
    System.out.println("共获取到:" + result.size() + "条数据");
}

2.3、爬取结果展示

Java爬虫爬取图片壁纸_第6张图片

三、缓存资源

3.1、过程与思路

  • 页面加载后,我们下滑或者分页时,没有请求日志;
  • 页面没有重新加载,但是数据在不断更新和加载中;
  • 当超过一定数量时,会有一次的请求日志显示出来;
  • 最后分析得到,数据是缓存到页面中的JS变量中了;

Java爬虫爬取图片壁纸_第7张图片

3.2、Java代码实现

变量名:window.__INITIAL_STATE__

缓存中有很多数据,我们以searchlist -> groupFixedResult -> groupPic中的数据为例,获取并解析里面的资源

资源地址:https://pic.sogou.com/pic/searchList.jsp?from=homeHotSearch&rcer=&spver=0&tagQSign=%E9%AB%98%E6%B8%85,3636d5ad&showMode=0&routeName=searchlist&keyword=美女

public static void main(String[] args) {
    // 请求资源地址得到页面数据
    Document document = Jsoup.parse(HttpUtil.get("https://pic.sogou.com/pic/searchList.jsp?from=homeHotSearch&rcer=&spver=0&tagQSign=%E9%AB%98%E6%B8%85,3636d5ad&showMode=0&routeName=searchlist&keyword=美女", 15000));
    String variableName = "window.__INITIAL_STATE__";
    // 解析得到所有的
                    
                    

你可能感兴趣的:(SpringBoot3.x,Java,java,爬虫,SpringBoot3.x,Java17,springboot3,js,html5)