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

.

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

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

相关文章

窗口虽小,功能良多:一篇文章带你玩转鸿蒙4的实况窗

在更新了鸿蒙4系统后&#xff0c;华为手机上多出了一个实况窗的功能。 实况窗功能可以实时显示部分应用的工作状态或者进度&#xff0c;比如外卖的进度、录音的时长等等&#xff0c;可以让我们在不打开手机应用的前提下也能了解到关键信息&#xff0c;极大地提升我们的生活体验…

闲鱼宝库亮相!闲鱼商品详情关键词搜索电商API接口助你畅享无尽好货!

随着互联网的快速发展&#xff0c;电商平台的崛起已经改变了人们的购物习惯。而在众多电商平台中&#xff0c;闲鱼作为一款社区二手交易平台&#xff0c;一直备受用户喜爱。如今&#xff0c;闲鱼宝库正式亮相&#xff0c;为用户带来了更加全面、详细的商品详情关键词搜索电商AP…

windows server 2019 云服务器看不见硬盘的解决方案

刚拿的windows server 服务器看不见硬盘&#xff0c;这是因为没有初始化数据盘的原因。 解决方案如下&#xff1a; 单击“服务器管理器”仪表盘。 弹出“服务器管理器”窗口&#xff0c;如图1所示。 “服务器管理器”页面右上方选择“工具 > 计算机管理”。 弹出“计算机管…

【转载】MyBatisCodeHelperPro最新版使用教程

在开发中编写生成bean&#xff0c;mapper&#xff0c;mapper.xml费时也费力&#xff0c;可以通过MyBatisCodeHelper-Pro自动生成bean&#xff0c;dao&#xff0c;mapper.xml等文件。 MyBatisCodeHelper-Pro是IDEA下的一个插件&#xff0c;类似于mybatis plugin&#xff0c;但可…

书生·浦语大模型实战营第四节课笔记及作业

XTuner 大模型单卡低成本微调实战 1 Finetune简介 大语言模型LLM是在海量的文本内容基础上&#xff0c;以无监督或半监督方式进行训练的。海量的文本内容赋予了大模型各种各样的行业知识。但是如果直接把大模型的知识用于生产实践&#xff0c;会发现回答不大满意。微调的目的…

adb wifi 远程调试 安卓手机 命令

使用adb wifi 模式调试需要满足以下前提条件&#xff1a; 手机 和 PC 需要在同一局域网下。手机需要开启开发者模式&#xff0c;然后打开 USB 调试模式。 具体操作步骤如下&#xff1a; 将安卓手机通过 USB 线连接到 PC。&#xff08;连接的时候&#xff0c;会弹出请求&#x…

零花钱也能设计精美网页!推荐几个免费设计素材站点!

UI设计师最怕什么&#xff1f; 没有创意&#xff0c;没有灵感&#xff0c;没有思路&#xff01; 在哪里可以得到idea&#xff1f;别担心&#xff0c;往下看&#xff01; 你知道网络有多大&#xff0c;你想要什么吗&#xff1f;今天&#xff0c;我想和大家分享一些宝藏网页设…

解决flask中jinja2插值变量变成字符串的办法

今天在通过使用{{ variable_name }}这种方式插入html内容时&#xff0c;发现变量内容到了页面中全部变成了字符串&#xff0c; python代码&#xff1a; return render_template(FilePath.file_path_to_page,md_contenthtml_content # 返回html内容 )html代码中插入&#xff1…

最简单爱心的解析

首先你需要了解爱心代码在直角坐标系的方程 数学知识&#xff1a;x 属于 -1.5 ~ 1.5 y 属于 -1 ~ 1.5 和 高中所学的线性规划 请看代码 #include <math.h> #include <stdlib.h> #include <Windows.h> #include <stdio.h> int main() { …

【REST2SQL】10 REST2SQL操作指南

【REST2SQL】01RDB关系型数据库REST初设计 【REST2SQL】02 GO连接Oracle数据库 【REST2SQL】03 GO读取JSON文件 【REST2SQL】04 REST2SQL第一版Oracle版实现 【REST2SQL】05 GO 操作 达梦 数据库 【REST2SQL】06 GO 跨包接口重构代码 【REST2SQL】07 GO 操作 Mysql 数据库 【RE…

谭浩强C语言程序设计习题-循环结构程序设计

最大公约数与最小公倍数 //辗转相除法求公约公倍 #include <stdio.h>int gcd(int a, int b) {return (a % b 0) ? b : gcd(b, a % b); }int main() {int m, n;scanf("%d %d", &m, &n); int ans gcd(m, n);printf("%d %d\n", ans, m * n…

ESP系列入门教程(四)——之MQTT通信实现设备反控【分别附上 ESP32 + ESP8266 的具体代码】

ESP系列入门教程<四> 概要技术名词简介● ESP系列简介● MQTT简介 硬件连接实现&#xff08;同教程2&#xff0c;没有变化&#xff09;代码实现●Demo&#xff1a;通过MQTT进行开关灯反控○ ESP8266代码○ ESP32代码 特别鸣谢 概要 最近在跟着几个大佬的教学视频做项目。…

02--数据定义语言DDL

1、数据定义语言DDL 1.1 操作数据库-DDL 创建数据库 create database 数据库名称; 创建数据库&#xff0c;并指定字符集 create database 数据库名称 character set 字符集名; 查询所有数据库的名称 show databases; 查询某个数据库的字符集:查询某个数据库的创建语句及字…

微服务介绍

背景 微服务是什么?杜克大学教授DanAriely说过一段非常出名的话&#xff0c;用来表述Big Data的发展现状。我觉得把这句话放到微服务身上也极其贴切。 Micro-services is like teenage sex: Everyone talks about it, nobody really knows how to do it, everyo ne thinks ev…

excel(vab)删除空行

删除第一、二、三列位空的所有行&#xff08;8000)行范围以内 代码如下&#xff1a; Sub Macro1()Dim hang As Integer For hang 8000 To 1 Step -1If Sheet1.Cells(hang, 1) "" And Sheet1.Cells(hang, 2) "" And Sheet1.Cells(hang, 3) "&quo…

系统性学习vue-vue中的ajax

vue中的ajax 配置代理常用发送Ajax请求方式跨域方式一方式二 vue-resource插槽默认插槽具名插槽作用域插槽 配置代理 常用发送Ajax请求方式 xhr new XMLHttpRequest() 在真正开发中不常用&#xff0c;比较麻烦jQuery 封装了xhraxios 封装了xhr 与jQuery相比优势是&#xff1a…

怎样才能找到合适的产品说明书模板 方法献上

制作一份专业而吸引人的产品手册对于企业来说至关重要。然而&#xff0c;对于许多企业和个人而言&#xff0c;制作产品手册可能是一个挑战&#xff0c;因为需要一定的设计和排版能力。为了帮助大家更轻松地制作出优质的产品手册&#xff0c;下面将向大家推荐三款优秀的产品手册…

Ovtio不同版本下载

关注 M r . m a t e r i a l , \color{Violet} \rm Mr.material\ , Mr.material , 更 \color{red}{更} 更 多 \color{blue}{多} 多 精 \color{orange}{精} 精 彩 \color{green}{彩} 彩&#xff01; 主要专栏内容包括&#xff1a; †《LAMMPS小技巧》&#xff1a; ‾ \textbf…

2024年汉字小达人区级选拔备考——附加题:汉字和国学常识

上海的孩子们已经率先开启了悠长的寒假生活。在寒假期间&#xff0c;除了完成寒假生活、学校安排和要求外&#xff0c;还可以做些什么呢&#xff1f;不妨来为2024年汉字小达人做些准备吧&#xff01;每天花个15分钟左右&#xff0c;背一背、做一做&#xff0c;轻松掌握汉字小达…

翻译: Streamlit从入门到精通 构建一个机器学习应用程序 三

Streamlit从入门到精通 系列&#xff1a; 翻译: Streamlit从入门到精通 基础控件 一翻译: Streamlit从入门到精通 显示图表Graphs 地图Map 主题Themes 二 1. 构建一个机器学习应用程序 在这一部分&#xff0c;我将带你了解我做的一个关于贷款预测的项目。 贷款的主要利润直…