相关推荐recommended
Java爬虫爬取图片壁纸
作者:mmseoamin日期:2024-01-22

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包



    org.jsoup
    jsoup
    1.15.3

项目依赖

pom.xml



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        3.2.1
        
    
    cn.molu
    jsoup
    0.0.1-SNAPSHOT
    jsoup
    
        java网络爬虫;更多技术分享地址请关注:https://blog.csdn.net/qq_51076413
    
    
        17
        17
        17
        17
        UTF-8
        UTF-8
    
    
        
        
            cn.hutool
            hutool-all
            5.8.24
        
        
        
            org.jsoup
            jsoup
            1.15.3
        
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
        
            org.springframework.boot
            spring-boot-devtools
            runtime
            true
        
        
        
            org.projectlombok
            lombok
            true
        
    
    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
                
                    
                        
                            org.projectlombok
                            lombok
                        
                    
                
            
        ·
    

爬取思路

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

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

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

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

      三、缓存资源:从页面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 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 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__";
    // 解析得到所有的