当前位置: 首页 > news >正文

Java爬虫爬取图片壁纸

Java爬虫

在这里插入图片描述

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包

<!--  解html析  -->
<dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.15.3</version>
</dependency>

项目依赖

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.1</version><relativePath/></parent><groupId>cn.molu</groupId><artifactId>jsoup</artifactId><version>0.0.1-SNAPSHOT</version><name>jsoup</name><description>java网络爬虫;更多技术分享地址请关注:https://blog.csdn.net/qq_51076413</description><properties><java.version>17</java.version><java.source.version>17</java.source.version><java.target.version>17</java.target.version><java.compiler.version>17</java.compiler.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding></properties><dependencies><!--  hutool工具包  --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.24</version></dependency><!--  jsoup解析包,核心  --><dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.15.3</version></dependency><!--  web依赖  --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--  热加载,修改代码后不需要手动重启(如果配置了JRebel可以不使用该插件)  --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><!--  lombok简化实体类  --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></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

定位资源所在位置
在这里插入图片描述

使用css选择器获取资源:

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

在这里插入图片描述

获取资源链接和标题:

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

在这里插入图片描述

示例代码如下:

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));// 只获取<body>标签中的元素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、过程与思路

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

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

在这里插入图片描述

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、爬取结果展示

三、缓存资源

3.1、过程与思路

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

在这里插入图片描述

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__";// 解析得到所有的<script>Elements scriptTags = document.getElementsByTag("script");// 过滤得到包含'__INITIAL_STATE__'的<script>List<String> collects = scriptTags.stream().map(Element::data).filter(data -> data.contains(variableName)).filter(StrUtil::isNotEmpty).toList();String scriptData = CollectionUtil.isEmpty(collects) ? "" : collects.get(0);// 截取js中'__INITIAL_STATE__'变量内容int startIndex = scriptData.indexOf("{");int endIndex = scriptData.lastIndexOf("}");// 得到js中'__INITIAL_STATE__'的json数据String jsonData = scriptData.substring(startIndex, endIndex + 1);// 将JS数据转为Java的JSON对象JSONObject jsonObject = JSONUtil.parseObj(jsonData);jsonObject = jsonObject.getJSONObject("searchlist");jsonObject = jsonObject.getJSONObject("groupFixedResult");JSONArray groupPicArray = jsonObject.getJSONArray("groupPic");Set<Map<String, String>> list = new HashSet<>();// 从JSON对象中提取资源数据getSource(groupPicArray, list);// 打印数据集System.out.println(list);System.out.println("共获取到:" + list.size() + "条数据");
}/*** 解析资源,获取资源数据** @param jsonArray 资源数据集* @param list      结果数据集*/
private static void getSource(JSONArray jsonArray, Set<Map<String, String>> list) {for (Object object : jsonArray) {if (object instanceof JSONArray item) {getSource(item, list);}if (object instanceof JSONObject item) {var map = new HashMap<String, String>();map.put("thumbUrl", item.getStr("thumbUrl"));map.put("title", item.getStr("title"));map.put("pageUrl", item.getStr("pageUrl"));map.put("picUrl", item.getStr("picUrl"));list.add(map);}}
}

3.3、爬取结果展示

四、完整测试代码

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.util.*;
import java.util.stream.Collectors;/*** @author 陌路* @apiNote 解析网页资源* @date 2024/1/15 19:55* @tool Created by IntelliJ IDEA*/
public class GetWebResourceTest {/*** 通过解析网页获取资源*/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=%E7%BE%8E%E5%A5%B3%E5%A3%81%E7%BA%B8#top=1395.199951171875&more=true", 15000));// 只获取<body>标签中的元素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() + "条数据");}/*** 通过API接口获取资源*/public static void main1(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() + "条数据");}/*** 通过js获取数据资源*/public static void main2(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__";// 解析得到所有的<script>Elements scriptTags = document.getElementsByTag("script");// 过滤得到包含'__INITIAL_STATE__'的<script>List<String> collects = scriptTags.stream().map(Element::data).filter(data -> data.contains(variableName)).filter(StrUtil::isNotEmpty).toList();String scriptData = CollectionUtil.isEmpty(collects) ? "" : collects.get(0);// 截取js中'__INITIAL_STATE__'变量内容int startIndex = scriptData.indexOf("{");int endIndex = scriptData.lastIndexOf("}");// 得到js中'__INITIAL_STATE__'的json数据String jsonData = scriptData.substring(startIndex, endIndex + 1);// 将JS数据转为Java的JSON对象JSONObject jsonObject = JSONUtil.parseObj(jsonData);jsonObject = jsonObject.getJSONObject("searchlist");jsonObject = jsonObject.getJSONObject("groupFixedResult");JSONArray groupPicArray = jsonObject.getJSONArray("groupPic");Set<Map<String, String>> list = new HashSet<>();// 从JSON对象中提取资源数据getSource(groupPicArray, list);// 打印数据集System.out.println(list);System.out.println("共获取到:" + list.size() + "条数据");}/*** 解析资源,获取资源数据** @param jsonArray 资源数据集* @param list      结果数据集*/private static void getSource(JSONArray jsonArray, Set<Map<String, String>> list) {for (Object object : jsonArray) {if (object instanceof JSONArray item) {getSource(item, list);}if (object instanceof JSONObject item) {var map = new HashMap<String, String>();map.put("thumbUrl", item.getStr("thumbUrl"));map.put("title", item.getStr("title"));map.put("pageUrl", item.getStr("pageUrl"));map.put("picUrl", item.getStr("picUrl"));list.add(map);}}}
}

五、下载资源

5.1、过程与思路

本案例仅以获取并解析JS资源为例来下载资源

下载图片资源,并将资源列表以json格式写入到本地(存入到数据库也可以,这里只写入到文件)

  • 根据上述代码,将获取到的数据资源下载到本地;
  • 将所有收集到的资源写入到文件中,方便于查看;

5.2、操作文件工具类

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.MD5;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import java.io.File;
import java.io.FileWriter;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Map;/*** @author 陌路* @apiNote 操作文件工具类* @date 2024/1/16 12:10* @tool Created by IntelliJ IDEA*/
@Slf4j
public class FileUtil {/*** 文件保存路径地址(修改为自己的地址)*/public static final String FILE_PATH = "D:/Code/picture/sougou/";/*** 写入文件** @param pathName 文件路径* @param suffix   文件类型,后缀名* @param data     数据集*/public static void write(String pathName, String suffix, String data) {File file = new File(pathName + suffix);try (FileWriter writer = new FileWriter(file)) {writer.write(JSONUtil.toJsonStr(data));writer.flush();} catch (Exception e) {log.error("写入数据出错了:" + e.getMessage(), e);}}/*** 获取文件路径** @param filePath 文件路径* @return 文件路径*/public static String getFilePath(String filePath) {filePath = StrUtil.isBlank(filePath) ? "" : filePath + "/";DateTime dateTime = new DateTime();String currentDate = dateTime.toString(DatePattern.NORM_DATE_PATTERN);return FILE_PATH + filePath + currentDate + "/";}/*** 获取文件名** @param title 标题* @return 文件名*/public static String getFileName(String title) {return StrUtil.isBlank(title) ? "" : MD5.create().digestHex(title, StandardCharsets.UTF_8);}/*** 下载文件** @param url      文件地址* @param filePath 文件路径* @param fileName 文件名* @param picUrl   图片地址*/@SuppressWarnings("all")public static void downloadFile(String url, String filePath, String fileName, String picUrl, boolean isDownload) {fileName = FileUtil.getFileName(fileName);File file = new File(filePath + "/" + fileName + ".jpg");try {if (!file.exists()) {file.getParentFile().mkdirs();file.createNewFile();}HttpUtil.downloadFile(url, file, 5000);} catch (Exception e) {if (!isDownload) {downloadFile(picUrl, filePath, fileName, picUrl, true);}log.error("下载文件出错:" + e.getMessage(), e);}}/*** 下载文件** @param filePath 文件路径* @param list     数据集*/public static void downloadFile(String filePath, Collection<Map<String, String>> list) {list.forEach(item -> FileUtil.downloadFile(item.get("thumbUrl"), filePath, item.get("title") + item.get("picUrl"), item.get("picUrl"), false));}
}

5.3、资源下载实现类

本案例仅以获取JS中的资源实现下载

/*** 解析html* @param keyword 搜索关键字* @return 爬取结果*/
public Set<Map<String, String>> parseHtmlByKeyword(String keyword) {Document document = Jsoup.parse(HttpUtil.get(UrlConstant.APP_BASE_URL + keyword, 15000));String variableName = "window.__INITIAL_STATE__";String scriptData = getJsonByScript(document.getElementsByTag("script"), variableName);int startIndex = scriptData.indexOf("{");int endIndex = scriptData.lastIndexOf("}");String jsonData = scriptData.substring(startIndex, endIndex + 1);JSONObject jsonObject = JSONUtil.parseObj(jsonData);jsonObject = jsonObject.getJSONObject("searchlist");jsonObject = jsonObject.getJSONObject("groupFixedResult");JSONArray groupPicArray = jsonObject.getJSONArray("groupPic");Set<Map<String, String>> list = new HashSet<>();getSource(groupPicArray, list);String filePath = FileUtil.getFilePath(keyword);// 资源数量小于100,直接下载,否则使用多线程下载long start = System.currentTimeMillis();// 是否使用多线程下载,资源数量>100的时候使用多线程if (list.size() < 100) {list.forEach(item -> FileUtil.downloadFile(item.get("thumbUrl"), filePath, item.get("title") + item.get("picUrl"), item.get("picUrl"), false));} else {multiThreaded(new ArrayList<>(list), keyword); // 多线程下载}long time = System.currentTimeMillis()- start;// 打印下载资源所耗时长log.info("共耗时:{}ms、{}s、{}m", time, (time / 1000), ((time / 1000) / 60));// 将资源数据写入到source.json文件中FileUtil.write(filePath + "/source", ".json", JSONUtil.toJsonStr(list));return list;
}

5.4、下载结果展示

在这里插入图片描述

5.5、调用示例

/*** @author 陌路* @apiNote 解析网页资源控制器* @date 2024/1/16 15:36* @tool Created by IntelliJ IDEA*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/parseHtml")
public class ParseHtmlController {private final ParseHtmlService parseHtmlService;/*** 根据关键字爬取数据** @param keyword 搜索关键字* @return 结果集*/@GetMapping("/query/{keyword}")public ResultVo<Collection<Map<String, String>>> parseHtml(@PathVariable String keyword) {if (StrUtil.isBlank(keyword)) return ResultVo.fail("请输入搜索关键字!");return ResultVo.ok(parseHtmlService.parseHtmlByKeyword(keyword));}
}

六、完整代码

完整代码:https://gitee.com/mmolu/open-source/tree/master/jsoup

七、说明

本实例仅学习供参考使用

请勿用来牟利或非法使用

本示例仅供学习参考,请勿用来牟利或非法使用!

本示例仅供学习参考,请勿用来牟利或非法使用!

本示例仅供学习参考,请勿用来牟利或非法使用!

更多技术分享请关注:.陌路-CSDN博客

创作不易,采集、转发请注明出处:https://blog.csdn.net/qq_51076413?type=blog

.

相关文章:

Java爬虫爬取图片壁纸

Java爬虫 以sougou图片为例&#xff1a;https://pic.sogou.com/ JDK17、SpringBoot3.2.X、hutool5.8.24实现Java爬虫&#xff0c;爬取页面图片 项目介绍 开发工具&#xff1a;IDEA2023.2.5 JDK&#xff1a;Java17 SpringBoot&#xff1a;3.2.x 通过 SpringBoot 快速构建开发环境…...

红队打靶练习:HOLYNIX: V1

目录 信息收集 1、arp 2、netdiscover 3、nmap 4、nikto whatweb 目录探测 1、gobuster 2、dirsearch 3、dirb 4、feroxbuster WEB sqlmap 1、爆库 2、爆表 3、爆列 4、爆字段 后台登录 1、文件上传 2、文件包含 3、越权漏洞 反弹shell 提权 总结 信息…...

elasticsearch[二]-DSL查询语法:全文检索、精准查询(term/range)、地理坐标查询(矩阵、范围)、复合查询(相关性算法)、布尔查询

ES-DSL查询语法&#xff08;全文检索、精准查询、地理坐标查询&#xff09; 1.DSL查询文档 elasticsearch 的查询依然是基于 JSON 风格的 DSL 来实现的。 1.1.DSL 查询分类 Elasticsearch 提供了基于 JSON 的 DSL&#xff08;Domain Specific Language&#xff09;来定义查…...

Microsoft Word 设置底纹

Microsoft Word 设置底纹 References 打开文档页面&#xff0c;选中特定段落或全部文档 在“段落”中单击“边框”下三角按钮 在列表中选择“边框和底纹”选项 在“边框和底纹”对话框中单击“底纹”选项卡 在图案样式和图案颜色列表中设置合适颜色的底纹&#xff0c;单击“确…...

【大数据】Flink 详解(九):SQL 篇 Ⅱ

《Flink 详解》系列&#xff08;已完结&#xff09;&#xff0c;共包含以下 10 10 10 篇文章&#xff1a; 【大数据】Flink 详解&#xff08;一&#xff09;&#xff1a;基础篇【大数据】Flink 详解&#xff08;二&#xff09;&#xff1a;核心篇 Ⅰ【大数据】Flink 详解&…...

workflow源码解析:GoTask

关于go task 提供了另一种更简单的使用计算任务的方法&#xff0c;模仿go语言实现的go task。 使用go task来实计算任务无需定义输入与输出&#xff0c;所有数据通过函数参数传递。 与ThreadTask 区别 ThreadTask 是有模板&#xff0c;IN 和 OUT&#xff0c; ThreadTask 依赖…...

SpringMVC入门案例

引言 Spring MVC是一个基于MVC架构的Web框架&#xff0c;它的主要作用是帮助开发者构建Web应用程序。它提供了一个强大的模型驱动的开发方式&#xff0c;可以帮助开发者实现Web应用程序的各种功能&#xff0c;如请求处理、数据绑定、视图渲染、异常处理等。 开发步骤 1.创建we…...

Docker本地私有仓库搭建配置指导

一、说明 因内网主机需要拉取镜像进行Docker应用&#xff0c;因此需要一台带外主机作为内网私有仓库来提供内外其他docker业务主机使用。参考架构如下&#xff1a; 相关资源&#xff1a;加密、Distribution registry、Create and Configure Docker Registry、Registry部署、D…...

python 通过定时任务执行pytest case

这段Python代码使用了schedule库来安排一个任务&#xff0c;在每天的22:50时运行。这个任务执行一个命令来运行pytest&#xff0c;并生成一个报告。 代码开始时将job_done变量设为False&#xff0c;然后运行预定的任务。一旦任务完成&#xff0c;将job_done设置为True并跳出循…...

算法面试题:合并两个有序链表

描述&#xff1a;给定两个按非递减顺序排列的链表&#xff0c;合并两个链表&#xff0c;并将结果按非递减顺序排列。 例如&#xff1a; # 链表 1: 1 -> 2 -> 4 # 链表 2: 1 -> 3 -> 4合并后的链表应该是&#xff1a;1 -> 1 -> 2 -> 3 -> 4 -> 4 …...

LaWGPT安装和使用教程的复现版本【细节满满】

文章目录 前言一、下载和部署1.1 下载1.2 环境安装1.3 模型推理 总结 前言 LaWGPT 是一系列基于中文法律知识的开源大语言模型。该系列模型在通用中文基座模型&#xff08;如 Chinese-LLaMA、ChatGLM等&#xff09;的基础上扩充法律领域专有词表、大规模中文法律语料预训练&am…...

西门子博途用SCL语言写的入栈出栈

1.用户登录 #pragma code ("useadmin.dll") #include "PWRT_api.h" #pragma code() PWRTLogin(1) 2.用户退出 #pragma code ("useadmin.dll") #include "PWRT_api.h" #pragma code() PWRTLogout(); 3.画面跳转 SetPictureName("P…...

密码产品推介 | 沃通安全电子签章系统(ES-1)

产品介绍 沃通安全电子签章系统&#xff08;ES-1&#xff09;是一款基于密码技术、完全自主研发的商用密码产品&#xff0c;严格遵循国家密码管理局制定的相关标准&#xff0c;可为企业和个人提供安全、合规的电子签章功能服务。产品的主要用途是为各类文书、合同、表单等电子…...

蓝桥杯真题(Python)每日练Day1

说明&#xff1a;在CSP认证的基础上&#xff08;可以看看本人CSP打卡系列的博客&#xff09;备赛2024蓝桥杯&#xff08;Python&#xff09;&#xff0c;本人专业&#xff1a;大数据与数据科学 因此对python要求熟练掌握&#xff0c;通过练习蓝桥杯既能熟悉语法又能锻炼算法和思…...

IDEA怎么用Devtools热部署

IDEA怎么用Devtools热部署 大家知道在项目开发过程中&#xff0c;有时候会改动代码逻辑或者修改数据结构&#xff0c;为了能使改动的代码生效&#xff0c;往往需要重启应用查看改变效果&#xff0c;这样会相当耗费时间。 重启应用其实就是重新编译生成新的Class文件&#xff0…...

boost.circular_buffer的使用和介绍

C 文章目录 C 很多时候&#xff0c;我们需要在内存中记录最近一段时间的数据&#xff0c;如操作记录等。由于这部分数据记录在内存中&#xff0c;因此并不能无限递增&#xff0c;一般有容量限制&#xff0c;超过后就将最开始的数据移除掉。在stl中并没有这样的数据结构&#xf…...

深入理解Java中的ThreadLocal

第1章&#xff1a;引言 大家好&#xff0c;我是小黑。今天咱们来聊聊ThreadLocal。首先&#xff0c;让咱们先搞清楚&#xff0c;ThreadLocal是个什么玩意儿。简单说&#xff0c;ThreadLocal可以让咱们在每个线程中创建一个变量的“私有副本”。这就意味着&#xff0c;每个线程…...

【重点】【DP】300. 最长递增子序列

题目 更好的方法是耐心排序&#xff0c;参见《算法小抄》的内容&#xff01;&#xff01;&#xff01; 法1&#xff1a;DP 基础解法必须掌握&#xff01;&#xff01;&#xff01; class Solution {public int lengthOfLIS(int[] nums) {if (nums null || nums.length 0) …...

使用freessl为网站获取https证书及配置详细步骤

文章目录 一、进入freessl网站二、修改域名解析记录三、创建证书四、配置证书五、服务启动 一、进入freessl网站 首先进入freessl网站&#xff0c;需要注册一个账号 freessl网站 进入网站后填写自己的域名 接下来要求进行DCV配置 二、修改域名解析记录 到域名管理处编辑域名…...

Java-初识正则表达式 以及 练习

目录 什么是正则表达式&#xff1f; 1. 正则表达式---字符类&#xff08;一个大括号匹配一个字符&#xff09;&#xff1a; 2. 正则表达式---预字符类&#xff08;也是匹配一个字符&#xff09;&#xff1a; 正则表达式---数量词 &#xff08;可以匹配多个字符&#xff09;…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

GO协程(Goroutine)问题总结

在使用Go语言来编写代码时&#xff0c;遇到的一些问题总结一下 [参考文档]&#xff1a;https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现&#xff1a; 今天在看到这个教程的时候&#xff0c;在自己的电…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)

在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...

C++_哈希表

本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、基础概念 1. 哈希核心思想&#xff1a; 哈希函数的作用&#xff1a;通过此函数建立一个Key与存储位置之间的映射关系。理想目标&#xff1a;实现…...