网页元素解析元素标签和style变更

前言

如何解析html标签?
如何给标签增加样式?

<div class="related-tags"><span>相关主题推荐:</span>a<a href='http://www.csdn.net/tag/标签' target="_blank">标签</a><a href="http://www.csdn.net/tag/java" target="_blank">java</a><a href="http://www.csdn.net/tag/团购" target="_blank">团购</a><a href="http://www.csdn.net/tag/体育" target="_blank">体育</a><a href="http://www.csdn.net/tag/搜狐" icon='a' target="_blank">搜狐</a>
<img src="/i/eg_tulip2.jpg"  alt="上海鲜花港 - 郁金香"><img src="/i/eg_tulip.jpg"  alt="上海鲜花港 - 郁金香" />  </div>

示例,需要提取这段html代码的a标签的内容,并且想改变style样式,如何处理?

实现代码

  1. 先定义网页节点,就节点的组成元素
import java.io.Serializable;
import java.util.List;/*** 网页节点** @author leng*/
public class WebNode implements Serializable {/*** 节点htmlString*/private String htmlString;/*** 节点中间的内容*/private String content;/*** 标签类型*/private String labelType;/*** 属性区的html内容*/private String attributeHtmlString;/*** 是否单节点*/private boolean isSingleNode;/*** 属性*/private List<AttributeHtml> attributeHtmlList;public String getHtmlString() {return htmlString;}public void setHtmlString(String htmlString) {this.htmlString = htmlString;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public String getAttributeHtmlString() {return attributeHtmlString;}public void setAttributeHtmlString(String attributeHtmlString) {this.attributeHtmlString = attributeHtmlString;}public String getLabelType() {return labelType;}public void setLabelType(String labelType) {this.labelType = labelType;}public boolean isSingleNode() {return isSingleNode;}public void setSingleNode(boolean isSingleNode) {this.isSingleNode = isSingleNode;}public List<AttributeHtml> getAttributeHtmlList() {return attributeHtmlList;}public void setAttributeHtmlList(List<AttributeHtml> attributeHtmlList) {this.attributeHtmlList = attributeHtmlList;}/*** 获取样式的属性** @return*/public AttributeHtml getStyle() {for (AttributeHtml attributeHtml : attributeHtmlList) {if (attributeHtml.getKey().equals("style")) {return attributeHtml;}}return null;}/*** 属性*/static class AttributeHtml {/*** 内容*/private String html;/*** 属性的key*/private String key;/*** 属性的值*/private String value;public String getHtml() {return html;}public void setHtml(String html) {this.html = html;}public String getKey() {return key;}public void setKey(String key) {this.key = key;}public String getValue() {return value;}public void setValue(String value) {this.value = value;}}
}
  1. 定义解析的核心
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/*** 网页工具*/
@Slf4j
public class WebpageUtil {/*** 从网页中获取标题** @param html* @return*/public static String getTitleFromHtmlString(String html) {int startIndex = html.indexOf("<title>");int endIndex = html.indexOf("</title>");if (startIndex == -1 || endIndex == -1) {return null;}String title = html.substring(startIndex + ("<title>".length()), endIndex);return title;}/*** 获取节点(不支持节点内包含节点)** @param html* @return*/public static List<String> getNode(String html, String nodeType) {String endStr = "</" + nodeType + ">";String regex;if (html.indexOf(endStr) > -1) {regex = "<a(\\s+\\w+\\s*=\\s*(\"|\')?(.*?)[\"|\'])*>(.*?)</a>";// 成对标签的元素(例如<a></a>)} else {regex = "<a(\\s+\\w+\\s*=\\s*(\"|\')?(.*?)[\"|\'|\\s])*\\s*\\/?>";// 单标签的元素(例如<img>)}regex = regex.replaceAll("a", nodeType);Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);Matcher m = p.matcher(html);ArrayList<String> list = new ArrayList<String>();while (m.find()) {String link = m.group(0).trim();list.add(link);}return list;}/*** 获取节点** @param html* @return*/public static List<WebNode> getNode2(String html, String labelType) {String endStr = "</" + labelType + ">";String regex;boolean isSingleNode = false;if (html.indexOf(endStr) > -1) {regex = "<a(\\s+\\w+\\s*=\\s*(\"|\')?(.*?)[\"|\'])*>(.*?)</a>";// 成对标签的元素(例如<a></a>)} else {isSingleNode = true;regex = "<a(\\s+\\w+\\s*=\\s*(\"|\')?(.*?)[\"|\'|\\s])*\\s*\\/?>";// 单标签的元素(例如<img>)}regex = regex.replaceAll("a", labelType);Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);Matcher m = p.matcher(html);List<WebNode> list = new ArrayList<>();while (m.find()) {WebNode node = new WebNode();node.setLabelType(labelType);node.setSingleNode(isSingleNode);String link = m.group(0).trim();node.setHtmlString(link);if (!isSingleNode) {int startIndex = link.substring(0, link.length() - 2).lastIndexOf(">");int endIndex = link.lastIndexOf("<");if (startIndex > -1 && endIndex > -1 && endIndex > startIndex) {String content = link.substring(startIndex + 1, endIndex);node.setContent(content);}}int startIndex2 = link.indexOf("<" + labelType);String str = null;if (isSingleNode) {str = link.substring(startIndex2 + ("<" + labelType).length());} else {int startIndex = link.substring(0, link.length() - 2).lastIndexOf(">");str = link.substring(startIndex2 + ("<" + labelType).length(), startIndex);}node.setAttributeHtmlString(str);
//            LinkedHashMap<String, String> params = new LinkedHashMap<>();
//            List<String> attributeList = new ArrayList<>();List<WebNode.AttributeHtml> attributeHtmls = new ArrayList<>();String[] arr = StrUtil.trim(str, "=").split(" ");if (null != arr && arr.length > 0) {for (String s : arr) {if (s.indexOf("=") > -1) {String key = s.substring(0, s.indexOf("="));String value = s.substring(s.indexOf("=") + 1);String k = key, v = value;if (key.startsWith("\'") || key.startsWith("\"")) {k = key.substring(1, key.length() - 1).trim();}if (value.startsWith("\'") || value.startsWith("\"")) {v = value.substring(1, value.length() - 1).trim();}WebNode.AttributeHtml attributeHtml = new WebNode.AttributeHtml();attributeHtml.setKey(k);attributeHtml.setValue(v);attributeHtml.setHtml(s);attributeHtmls.add(attributeHtml);
//                        params.put(k, v);}}}
//            node.setAttributeHtmlList(attributeList);
//            node.setAttributeMap(params);node.setAttributeHtmlList(attributeHtmls);list.add(node);}return list;}/*** 改变样式,会覆盖原来的节点** @param webNode* @param newStyle 新样式会覆盖旧的样式,不要写style,直接传入样式内容就可以了* @return*/public static WebNode changeStyle(WebNode webNode, LinkedHashMap<String, String> newStyle) throws Exception {if (null == webNode || null == newStyle || newStyle.size() == 0) {return null;}StringBuffer stringBuffer = new StringBuffer();newStyle.forEach((k, v) -> {if (null != v) {stringBuffer.append(k).append(":").append(v);}});List<WebNode.AttributeHtml> attributeHtmlList = webNode.getAttributeHtmlList();String htmlString = webNode.getHtmlString();String labelType = webNode.getLabelType();WebNode.AttributeHtml oldStyle = webNode.getStyle();String str = null;String newStyleStr = "style=\"" + stringBuffer.toString() + "\"";//新样式要拼接if (null == oldStyle) {//原来没有就增加样式,标签的尾部,就是>的前面str = htmlString.replaceFirst(">", " " + newStyleStr + ">");} else {//取代旧的样式String html = oldStyle.getHtml();str = htmlString.replaceFirst(html, newStyleStr);}List<WebNode> node2 = getNode2(str, labelType);try {WebNode webNode2 = node2.get(0);BeanUtils.copyProperties(webNode2, webNode);return webNode;} catch (Exception e) {log.error("解析标签发生错误:" + str, e);throw new Exception("解析标签发生错误");}}/*** 添加样式,如果原来style,则新增,如果有替换同样的样式** @param webNode* @param newStyle 新增的样式* @return*/public static WebNode addStyle(WebNode webNode, LinkedHashMap<String, String> newStyle) throws Exception {if (null == webNode || null == newStyle || newStyle.size() == 0) {return null;}List<WebNode.AttributeHtml> attributeHtmlList = webNode.getAttributeHtmlList();String htmlString = webNode.getHtmlString();String labelType = webNode.getLabelType();WebNode.AttributeHtml oldStyle = webNode.getStyle();String str = "";if (null == oldStyle) {StringBuffer stringBuffer = new StringBuffer();newStyle.forEach((k, v) -> {if (null != v) {stringBuffer.append(k).append(":").append(v).append(";");}});String newStyleStr = "style=\"" + stringBuffer.toString() + "\"";//新样式要拼接//原来没有就增加样式,标签的尾部,就是>的前面str = htmlString.replaceFirst(">", " " + newStyleStr + ">");} else {//取代旧的样式String html = oldStyle.getHtml();String styleContent = oldStyle.getValue();str = htmlString;LinkedHashMap<String, String> oldStyleMap = StrUtil.stringToMap(styleContent, ";", ":");oldStyleMap = null == oldStyleMap ? new LinkedHashMap<>() : oldStyleMap;//变更样式Iterator<Map.Entry<String, String>> iterator = newStyle.entrySet().iterator();StringBuffer addStyleSb = new StringBuffer();LinkedHashMap<String, String> replaceList = new LinkedHashMap<>();while (iterator.hasNext()) {Map.Entry<String, String> next = iterator.next();String k = next.getKey();if (StringUtils.isEmpty(k)) {continue;}String v = next.getValue();String oldStyleAttr = oldStyleMap.get(k);if (null != oldStyleAttr) {String oldSt = k + ":" + oldStyleAttr;String newSt = k + ":" + v;if (StringUtils.isEmpty(v)) {
//                        str = str.replaceFirst(oldSt, "");replaceList.put(oldSt, "");//如果不设置值,则表示清除样式} else {
//                        str = str.replaceFirst(oldSt, newSt);replaceList.put(oldSt, newSt);}} else {if (StringUtils.isNotEmpty(v)) {addStyleSb.append(k).append(":").append(v).append(";");}}}//先追加新样式if (addStyleSb.length() > 0) {String oldSt = oldStyle.getHtml();String newSt = oldSt.substring(0, oldSt.length() - 1) + addStyleSb + "\"";str = str.replaceFirst(oldSt, newSt);}//再替换已有样式,如果顺序执行反了,就会导致无法使用样式错误Iterator<Map.Entry<String, String>> iterator1 = replaceList.entrySet().iterator();while (iterator1.hasNext()) {Map.Entry<String, String> next = iterator1.next();String k = next.getKey();String v = next.getValue();str = str.replaceFirst(k, v);}}List<WebNode> node2 = getNode2(str, labelType);try {WebNode webNode2 = node2.get(0);BeanUtils.copyProperties(webNode2, webNode);return webNode;} catch (Exception e) {log.error("解析标签发生错误:" + str, e);throw new Exception("解析标签发生错误");}}
}
  1. 其它工具类
import org.apache.commons.lang3.StringUtils;import java.util.*;/*** @Description 描述* @Author 作者* @Date 2024/3/29* @return*/
public class StrUtil {/*** 获取两个字符串之间的字符串内容** @param sourceString 源字符串* @param startString  起始字符串* @param endString    终止字符串(从起始字符串开始计算),如果找不到,则返回null* @return* @author lengchengzhen* @date 2024-3-29*/public static String getBetweenString(String sourceString, String startString, String endString) {if (StringUtils.isEmpty(sourceString) || StringUtils.isEmpty(startString) || StringUtils.isEmpty(endString)) {return null;}int stIndex = sourceString.indexOf(startString);if (stIndex == -1) {return null;}String str2 = sourceString.substring(stIndex + startString.length());int endIndex = str2.indexOf(endString);if (endIndex == -1) {return null;}return str2.substring(0, endIndex);}public static boolean isEmpty(String string){return null==string||string.equals("");}public static boolean isNotEmpty(String string){return null!=string&&!string.equals("");}/*** 将字符串string重复n次,通过seg进行分割连接** @param string 需要重复的字符串* @param n      重复次数* @param seg    分割字符串,如果等于null,则为""* @return*/public static String repeatString(String string, int n, String seg) {if (null == seg) {seg = "";}/*** 并非不用其他方法实现,因为这种方法是性能最好的写法*/StringBuffer sb = new StringBuffer();for (int i = 0; i < n; i++) {sb.append(string).append(seg);}return sb.substring(0, sb.length() - seg.length());// return String.join(seg, Collections.nCopies(n, string));}/*** 将num重复n次,通过seg进行分割符号连接** @param num 需要重复的数值* @param n   重复次数* @param seg 分割字符串,如果等于null,则为""* @return*/public static String repeatString(int num, int n, String seg) {return repeatString(num + "", n, seg);}/*** 将num重复n次,分割字符串为英文逗号","** @param num 需要重复的数值* @param n   重复次数* @return*/public static String repeatString(int num, int n) {return repeatString(num + "", n, ",");}/*** 将int数组转换成字符串** @param intArray* @return*/public static String IntArrayToString(Integer[] intArray) {if (null != intArray) {StringBuffer sb = new StringBuffer();for (Integer a : intArray) {if (null != a) {sb.append(",").append(a);}}if (sb.length() > 0) {return sb.substring(1);}}return null;}/*** 字符串str是否存在于字符串array数组中** @param array      字符串数组* @param str        字符串* @param ignoreCase 是否忽略大小写* @return*/public static boolean isExist(String[] array, String str, boolean ignoreCase) {if (null != array && null != str) {for (String s : array) {if (ignoreCase) {if (s.equalsIgnoreCase(str)) {return true;}} else {if (s.equals(str)) {return true;}}}}return false;}/*** 将字符串按照splitStr进行分割,并转换成{@code List<Integer>}集合** @param string* @param splitStr* @return*/public static List<Integer> parseList(String string, String splitStr) {if (isEmpty(string)) {return null;}String[] arrays = string.split(splitStr);List<Integer> list = new ArrayList<>(arrays.length);for (String str : arrays) {try {if (isNotEmpty(str)) {Integer num = Integer.parseInt(str);list.add(num);}} catch (Exception e) {}}return list;}/*** 将字符串按照逗号,进行分割,并转换成{@code List<Integer>}集合** @param string* @return*/public static List<Integer> parseList(String string) {return parseList(string, ",");}/*** 将字符串按照splitStr进行分割,并转换成{@code Set<Integer>}集合** @param string* @param splitStr* @return*/public static Set<Integer> parseSet(String string, String splitStr) {if (isEmpty(string)) {return null;}String[] arrays = string.split(splitStr);Set<Integer> set = new HashSet<>();for (String str : arrays) {try {if (isNotEmpty(str)) {Integer num = Integer.parseInt(str);set.add(num);}} catch (Exception e) {}}return set;}/*** 将字符串按照逗号,进行分割,并转换成{@code Set<Integer>}集合** @param string* @return*/public static Set<Integer> parseSet(String string) {return parseSet(string, ",");}/*** 将字符串按照splitStr进行分割,并转换成{@code Set<String>}集合** @param string* @param splitStr* @return*/public static Set<String> parseSetString(String string, String splitStr) {if (isEmpty(string)) {return null;}String[] arrays = string.split(splitStr);Set<String> set = new HashSet<>();for (String str : arrays) {try {set.add(str);} catch (Exception e) {}}return set;}/*** 将字符串转换成map,示例 string="1-2,3-4,5-6",seg1=",",seg2="-" 转换为map后,{1=2,3=4,5=6}** @param string 被切割的字符串* @param seg1   分割符号1   示例:,* @param seg2   分割符号2   示例: -* @return*/public static LinkedHashMap<String, String> stringToMap(String string, String seg1, String seg2) {if (isNotEmpty(string)) {String[] arr = string.split(seg1);LinkedHashMap<String, String> map = new LinkedHashMap<>(arr.length);for (String s : arr) {if (isNotEmpty(s)) {String[] arr2 = s.split(seg2);if (arr2.length == 1) {map.put(arr2[0], null);} else if (arr2.length >= 2) {map.put(arr2[0], arr2[1]);}}}return map;}return null;}/*** 将字符串转换成map,示例 string="1-2,3-4,5-6" 转换为map后,{1=2,3=4,5=6}** @param string* @return*/public static LinkedHashMap<String, String> stringToMap(String string) {return stringToMap(string, ",", "-");}/*** 替换首逗号,如果字符串的开头不是逗号,则原样返还** @param str* @return*/public static String repaceFirstComma(String str) {if (null == str) {return null;}if (str.startsWith(",")) {return str.substring(1);}return str;}/*** 字符串数组转int数组** @param array* @return*/public static int[] strArrayToIntArray(String[] array) {int[] intArray = new int[0];for (String s : array) {if (isNotEmpty(s)) {intArray = Arrays.copyOf(intArray, intArray.length + 1);intArray[intArray.length - 1] = Integer.parseInt(s);}}return intArray;}/*** 去掉指定字符前后的空格** @param string* @param specialStr* @return*/public static String trim(String string, String specialStr) {if (null == string) {return null;}String s1 = " " + specialStr;while (string.indexOf(s1) > -1) {string = string.replaceAll(s1, specialStr);}String s2 = specialStr + " ";while (string.indexOf(s2) > -1) {string = string.replaceAll(s2, specialStr);}return string;}
}
  1. 测试示例
@Testpublic void testWebNode() throws Exception {String str = "<div class=\"related-tags\">\n" + "    <span>相关主题推荐:</span>\n"+ "      a<a href=\'http://www.csdn.net/tag/标签\' target=\"_blank\">标签</a>\n"+ "      <a href=\"http://www.csdn.net/tag/java\" target=\"_blank\">java</a>\n"+ "      <a href=\"http://www.csdn.net/tag/团购\" target=\"_blank\">团购</a>\n"+ "      <a href=\"http://www.csdn.net/tag/体育\" target=\"_blank\">体育</a>\n"+ "      <a href=\"http://www.csdn.net/tag/搜狐\" icon='a' target=\"_blank\">搜狐</a>\n"+ "<img src=\"/i/eg_tulip2.jpg\"  alt=\"上海鲜花港 - 郁金香\"><img src=\"/i/eg_tulip.jpg\"  alt=\"上海鲜花港 - 郁金香\" />  </div>";List<String> list = WebpageUtil.getNode(str, "a");System.out.println("-------a标签原内容------");list.forEach(c -> {System.out.println(c);});List<WebNode> list2 = WebpageUtil.getNode2(str, "a");System.out.println("-------解析后的数据------");list2.forEach(c -> {System.out.println("内容:" + c.getContent());System.out.println("标签类型:" + c.getLabelType());System.out.println("标签的参数:" + JSONObject.toJSONString(c.getAttributeHtmlList()));});List<WebNode> list3 = WebpageUtil.getNode2(str, "a");LinkedHashMap<String, String> style = new LinkedHashMap<>();style.put("background-color", "red");for (WebNode webNode : list3) {WebpageUtil.changeStyle(webNode, style);}System.out.println("-------改变样式后(如果原来有style则覆盖)------");list3.forEach(c -> {System.out.println("-----------------------------------");System.out.println("标签html:" + c.getHtmlString());System.out.println("内容:" + c.getContent());System.out.println("标签类型:" + c.getLabelType());System.out.println("标签的参数:" + JSONObject.toJSONString(c.getAttributeHtmlList()));});List<WebNode> list4 = WebpageUtil.getNode2(str, "a");LinkedHashMap<String, String> style2 = new LinkedHashMap<>();style2.put("background-color", "green");for (WebNode webNode : list4) {WebpageUtil.addStyle(webNode, style2);}System.out.println("-------改变样式后(增加样式,不覆盖原来样式,如果是同属性样式,则覆盖,例如原来的bgcolor=red,新增样式bgcolor=green,则替换,否则新增,对其它样式无影响)------");list4.forEach(c -> {System.out.println("-----------------------------------");System.out.println("标签html:" + c.getHtmlString());System.out.println("内容:" + c.getContent());System.out.println("标签类型:" + c.getLabelType());System.out.println("标签的参数:" + JSONObject.toJSONString(c.getAttributeHtmlList()));});}

执行结果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

【STM32】输入捕获应用-测量脉宽或者频率(方法1)

图1 脉宽/频率测量示意图 1 测量频率 当捕获通道TIx 上出现上升沿时&#xff0c;发生第一次捕获&#xff0c;计数器CNT 的值会被锁存到捕获寄存器CCR中&#xff0c;而且还会进入捕获中断&#xff0c;在中断服务程序中记录一次捕获&#xff08;可以用一个标志变量来记录&#…

CC攻击的有效应对方案

随着互联网的发展&#xff0c;网络安全问题愈发突出。CC攻击&#xff08;Challenge Collapsar Attack&#xff09;&#xff0c;一种针对Web应用程序的分布式拒绝服务&#xff08;DDoS&#xff09;攻击方式&#xff0c;已经成为许多网络管理员和网站拥有者不得不面对的重大挑战。…

Fantasy Icons Megapack(梦幻盔甲宝石图标魔法道具图标集)

所有图标都具备高质量&#xff0c;并以专业水平实施。任何幻想风格游戏的上佳选择。 - 可更新的超级资源包&#xff1b; - 每个图标的大小均为 256x256 像素 (PNG)&#xff1b; - 总计 2672 个独一无二的图标&#xff1b; - 所有图标均具有透明背景。 超级资源包内置&#xff1…

Redisson原理解析

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…

如何通过“小猪APP分发”轻松实现应用分发

你是否也在为应用分发发愁&#xff1f; 还记得那些日子吗&#xff1f;你花费了大量的时间和精力开发了一款出色的应用&#xff0c;但却在分发和推广环节遇到了瓶颈。是的&#xff0c;无论你的应用多么优秀&#xff0c;如果不能顺利分发给用户&#xff0c;那一切都是徒劳的。别…

[c++刷题]贪心算法.N01

题目如上: 首先通过经验分析&#xff0c;要用最少的减半次数&#xff0c;使得数组总和减少至一半以上&#xff0c;那么第一反应就是每次都挑数组中最大的数据去减半&#xff0c;这样可以是每次数组总和值减少程度最大化。 代码思路:利用大根堆去找数据中的最大值&#xff0c;…

[数据集][实例分割]减速带分割数据集json+yolo格式5400张1类别

数据集格式&#xff1a;labelme格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件以及对应yolo格式txt) 图片数量(jpg文件个数)&#xff1a;5400 标注数量(json文件个数)&#xff1a;5400 标注数量(txt文件个数)&#xff1a;5400 标注类别数&#xff1a;1 标注…

体验版小程序访问不到后端接口请求失败问题解决方案

文章目录 解决方案一&#xff1a;配置合法域名解决方案二&#xff1a;开发调试模式第一步&#xff1a;进入开发调试模式第二步&#xff1a;启用开发调试 注意事项结语 &#x1f389;欢迎来到Java面试技巧专栏~探索Java中的静态变量与实例变量 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&…

牛客链表刷题(一)

目录 题目一&#xff1a;反转链表 代码&#xff1a; 题目二&#xff1a;链表内指定区间反转 代码&#xff1a; 题目一&#xff1a;反转链表 代码&#xff1a; import java.util.*;/** public class ListNode {* int val;* ListNode next null;* public ListNode(int …

2024 年最新 Python 使用 gewe 框架搭建微信机器人实现语音智能回复(详细教程)

Gewe 个微框架 GeWe&#xff08;个微框架&#xff09;是一个创新性的软件开发框架&#xff0c;专注于IPAD协议&#xff0c;为个人微信号以及企业信息安全提供了强大的功能和保障。GeWe的设计旨在简化开发过程&#xff0c;使开发者能够高效、灵活地构建和定制通信协议&#xff…

unity基础(五)地形详解

目录 一 创建地形 二 调整地形大小 三 创建相邻地形 四 创建山峰 五 创建树木 七 添加风 八 添加水 简介: Unity 中的基础地形是构建虚拟场景的重要元素之一。 它提供了一种直观且灵活的方式来创建各种地形地貌&#xff0c;如山脉、平原、山谷等。 通过 Unity 的地形…

力扣384. 打乱数组

Problem: 384. 打乱数组 文章目录 题目描述思路复杂度Code 题目描述 思路 打乱数组的主要算法&#xff1a; 从1 - n每次生成[i ~ n - i]的一个随机数字&#xff0c;再将原数组下标位置为i的元素和该随机数字位置的元素交换 复杂度 打乱数组的主要算法 时间复杂度: O ( n ) O(…

【Attack】拓扑缺陷图注入攻击

TDGIA: 图神经网络的有效注入攻击 图注入攻击下 GNN 的脆弱性TDGIA框架拓扑缺陷边选择平滑的对抗优化整体攻击流程 KDD’21 &#x1f604; 图注入攻击&#xff1a;攻击者无法修改输入图的现有link结构和节点属性&#xff0c;而是通过向其中注入对抗性节点来执行攻击。 图注入…

Linux操作系统学习路线

本文来自Qwen2大模型&#xff1a; Linux操作系统的全面学习是一个渐进的过程&#xff0c;涵盖从基础知识到高级特性的多个阶段。以下是一份详细的Linux操作系统学习路线图&#xff0c;包括各个阶段的学习目标、建议的学习资源和实践步骤。 1. Linux 基础知识与安装 学习目标&a…

vite构建的ts项目配置src别名@

一、安装types/node npm install types/node 二、vite.config.ts 文件中配置以下内容 resolve: {alias: {: path.resolve(__dirname, ./src),},}, 三、 tsconfig.json 文件中compilerOptions下配置以下内容 /* 配置 */"baseUrl": ".","paths":…

深度学习长文|使用 JAX 进行 AI 模型训练

引言 在人工智能模型的开发旅程中&#xff0c;选择正确的机器学习开发框架是一项至关重要的决策。历史上&#xff0c;众多库都曾竞相争夺“人工智能开发者首选框架”这一令人垂涎的称号。&#xff08;你是否还记得 Caffe 和 Theano&#xff1f;&#xff09;在过去的几年里&…

Python | Leetcode Python题解之第149题直线上最多的点数

题目&#xff1a; 题解&#xff1a; class Solution:def maxPoints(self, points: List[List[int]]) -> int:n len(points)if n < 2:return nres 2for i in range(n):x1, y1 points[i][0], points[i][1]has {}for j in range(i 1, n):x2, y2 points[j][0], points…

随心笔记,第六更

目录 一、 三步构建 XML转成java bean 1.XML转XSD 2.XSD转JavaBean 3.jaxb 工具类 4.测试 &#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是「Leen」。刚工作几年&#xff0c;想和大家一同进步&am…

ESP RainMaker®为企业提供AIoT云解决方案,启明云端乐鑫代理商

在AIoT的浪潮中&#xff0c;企业面临着前所未有的机遇与挑战。如何快速响应市场变化&#xff0c;开发出具有竞争力的智能产品&#xff1f;如何确保数据安全&#xff0c;同时实现高效的设备管理&#xff1f;这些问题&#xff0c;ESP RainMaker给出了答案。 ESP RainMaker是一个…

STM32程序启动过程

&#xff08;1&#xff09;首先对栈和堆的大小进行定义&#xff0c;并在代码区的起始处建立中断向量表&#xff0c;其第一个表项是栈顶地址&#xff08;32位&#xff09;&#xff0c;第二个表项是复位中断服务入口地址&#xff1b; &#xff08;2&#xff09;然后执行复位中断&…