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

SpiderFlow平台v0.5.0之引入selenium插件

引入selenium插件

  • 首先到码云下载插件点击下载​编辑到本地并导入到工作空间或安装到maven库
  • 在spider-flow/spider-flow-web/pom.xml中引入插件
<!-- 引入selenium插件 -->
<dependency><groupId>org.spiderflow</groupId><artifactId>spider-flow-selenium</artifactId>
</dependency>
  • 在spider-flow/spider-flow-web/application.properties中配置驱动路径

  • chrome驱动下载地址:https://developer.chrome.com/docs/chromedriver/downloads?hl=zh-cn#chromedriver_900443024

  • firefox驱动下载地址:https://github.com/mozilla/geckodriver/releases​

安装错误处理

1、无法找到二进制文件

报错信息:

org.openqa.selenium.WebDriverException: Cannot find firefox binary in PATH. Make sure firefox is installed. OS appears to be: LINUX
Build info: version: 'unknown', revision: 'unknown', time: 'unknown'
System info: host: 'zyldev01', ip: '10.0.3.190', os.name: 'Linux', os.arch: 'amd64', os.version: '3.10.0-1160.el7.x86_64', java.version: '1.8.0_181'
Driver info: driver.version: FirefoxDriverat org.openqa.selenium.firefox.FirefoxBinary.<init>(FirefoxBinary.java:116)at java.util.Optional.orElseGet(Optional.java:267)at org.openqa.selenium.firefox.FirefoxOptions.getBinary(FirefoxOptions.java:218)at org.openqa.selenium.firefox.FirefoxDriver.toExecutor(FirefoxDriver.java:155)at org.openqa.selenium.firefox.FirefoxDriver.<init>(FirefoxDriver.java:120)at org.spiderflow.selenium.driver.FireFoxDriverProvider.getWebDriver(FireFoxDriverProvider.java:87)at org.spiderflow.selenium.executor.shape.SeleniumExecutor.execute(SeleniumExecutor.java:111)at org.spiderflow.core.Spider.lambda$executeNode$4(Spider.java:285)at com.alibaba.ttl.TtlRunnable.run(TtlRunnable.java:59)at org.spiderflow.concurrent.SpiderFlowThreadPoolExecutor$SubThreadPoolExecutor.lambda$submitAsync$0(SpiderFlowThreadPoolExecutor.java:152)at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)at java.util.concurrent.FutureTask.run(FutureTask.java:266)at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)at java.util.concurrent.FutureTask.run(FutureTask.java:266)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)at java.lang.Thread.run(Thread.java:748)

该错误信息表明 WebDriver 无法找到 Firefox 浏览器的二进制文件,原因可能是 Firefox 浏览器没有正确安装,或者它没有添加到 PATH 环境变量中。解决此问题,可以通过以下几个步骤进行:

1)确保 Firefox 已安装

首先,请确认 Firefox 浏览器已正确安装在系统上。可以通过以下命令检查:

firefox --version

如果系统提示 command not found 或类似错误,表示 Firefox 没有安装。你可以通过以下命令安装 Firefox:

对于基于 Debian 的系统(如 Ubuntu)

sudo apt update sudo apt install firefox

对于基于 RHEL/CentOS 的系统

sudo yum install firefox

2)设置 Firefox 路径

如果 Firefox 已安装,但 WebDriver 仍然提示找不到 Firefox 二进制文件,则需要确保 Firefox 的安装路径添加到 PATH 环境变量中。

  • 查找 Firefox 安装路径

    运行以下命令来查找 Firefox 的安装路径:

    which firefox

    该命令会返回 Firefox 的完整路径,例如:/usr/bin/firefox

  • 设置 Firefox 路径

    可以通过设置环境变量 webdriver.firefox.bin 来指定 Firefox 的二进制文件路径。在 Selenium 测试脚本中,使用如下代码:

    System.setProperty("webdriver.firefox.bin", "/usr/bin/firefox");

    或者,如果你使用的是 FirefoxOptions

    FirefoxOptions options = new FirefoxOptions(); options.setBinary("/usr/bin/firefox"); WebDriver driver = new FirefoxDriver(options);

    其中 /usr/bin/firefox 替换为实际的 Firefox 安装路径。

3.)确保 FirefoxDriver 与 Firefox 版本匹配

确认你下载的 geckodriver(Firefox 的 WebDriver)与系统中安装的 Firefox 版本兼容。你可以通过以下命令检查 Firefox 的版本:

firefox --version

然后下载与 Firefox 版本匹配的 geckodriver,可以从 GeckoDriver Releases 页面下载。

4) 添加 Firefox 路径到 PATH

如果你希望 Firefox 能在任何地方通过命令行访问,确保 Firefox 路径添加到系统的 PATH 环境变量中。你可以通过以下命令将其添加到 .bashrc.bash_profile 文件中:

echo "export PATH=$PATH:/usr/bin" >> ~/.bashrc 
source ~/.bashrc

如果 Firefox 安装在其他路径,只需修改 /usr/bin 为实际路径。

5)确认 geckodriver 已正确安装

geckodriver 必须在 PATH 中,或者你可以手动设置其路径。你可以通过以下命令确认 geckodriver 是否已安装并正确配置:

geckodriver --version

如果没有安装 geckodriver,可以从以下地址下载适合你操作系统的版本:

GeckoDriver 下载页面

确保 geckodriver 已添加到 PATH 中,或者在代码中显式设置其路径,例如:

System.setProperty("webdriver.gecko.driver", "/path/to/geckodriver");

总结

  • 确保 Firefox 已安装且可执行。
  • 检查 Firefox 的路径并确保在环境变量 PATH 中。
  • 下载与 Firefox 版本兼容的 geckodriver 并配置正确的路径。

按照这些步骤,你应该能够解决 Cannot find firefox binary in PATH 的问题。如果问题依然存在,可能需要重新检查 Firefox 和 geckodriver 的安装路径配置。

2、浏览器启动失败

报错:

org.openqa.selenium.WebDriverException: Process unexpectedly closed with status 1

org.openqa.selenium.WebDriverException: Process unexpectedly closed with status 1 是 Selenium 中常见的错误之一。这个错误通常发生在 WebDriver 启动浏览器时,浏览器驱动(例如 chromedrivergeckodriver)未能正确启动,或者浏览器本身遇到了启动问题。错误的状态码 1 表示程序退出时发生了异常。

以下是一些常见的原因以及对应的解决方案:

1)浏览器和驱动不匹配

浏览器版本和 WebDriver 版本必须匹配。如果你使用的是较新的浏览器版本,但驱动程序版本较旧,或者反之,都可能导致 WebDriver 启动失败。

解决方法

  • 检查浏览器版本:查看你的浏览器(例如 Chrome 或 Firefox)版本。
  • 下载兼容的 WebDriver 版本:根据你的浏览器版本下载与之匹配的 WebDriver。

比如:

  • 对于 Chrome,你可以访问 chromedriver download 来下载适合你 Chrome 版本的 chromedriver
  • 对于 Firefox,你可以访问 geckodriver releases 来下载与 Firefox 版本匹配的 geckodriver

2)驱动文件不可执行或权限问题

如果驱动程序文件没有正确的执行权限,Selenium 启动时会遇到问题。

解决方法: 你需要确保驱动程序文件具有可执行权限。在 Linux 或 macOS 系统中,可以运行以下命令来设置文件的执行权限:

chmod +x /path/to/your/driver

3) 缺少必要的依赖库(特别是在 Linux 上)

对于 Linux 系统,某些浏览器驱动(尤其是 chromedriver)可能需要依赖特定的库。如果这些库缺失,WebDriver 启动会失败。

解决方法: 你可以通过以下命令安装缺少的依赖库(例如,在 Ubuntu 上):

sudo apt-get install libnss3 libgdk-pixbuf2.0-0 libx11-xcb1

这些是 Chromium 和 chromedriver 通常需要的库。

4)浏览器启动异常

有时浏览器本身的问题(例如设置了某些配置)也会导致 WebDriver 启动失败。

还有就是如果你的爬虫平台布置在服务器上,你本地要调用浏览器的话,可能由于驱动差异会调用不起来

解决方法

  • 确保没有后台的浏览器实例运行。
  • 尝试使用无头模式(headless mode)启动浏览器,特别是在 CI/CD 环境或没有图形界面的服务器上。

可以设置以下参数来启动无头模式:

浏览器有头和无头模式了解 

浏览器的“无头模式”(Headless Mode)和“有头模式”(Headed Mode)是指浏览器是否以图形用户界面(GUI)形式显示出来的两种运行方式。这两种模式的主要区别在于是否显示浏览器窗口。

1. 有头模式(Headed Mode)

  • 定义:有头模式是浏览器的常规运行模式,指的是浏览器启动时会弹出一个可视的窗口,用户可以看到浏览器的图形界面并与之交互。
  • 特点
    • 浏览器窗口可见,用户可以直接操作。
    • 页面加载、渲染和交互都可以通过图形界面直观地进行。
    • 适用于需要与页面直接交互的场景(例如手动测试、用户实际使用的场景等)。
  • 使用场景
    • 自动化测试时调试,开发人员希望通过可视化界面查看页面元素的变化。
    • 需要与浏览器进行实时交互的场景。

2. 无头模式(Headless Mode)

  • 定义:无头模式是指浏览器启动时不显示图形界面,而是在后台运行,所有的渲染和操作都是在无图形界面的环境下进行的。
  • 特点
    • 浏览器没有窗口显示,也不能与其交互。
    • 通常更快速,因为不需要渲染图形界面,减少了系统资源的占用。
    • 非常适合自动化测试和大规模的网页抓取。
    • 能够在没有显示器或图形界面的环境中运行(如服务器环境、Docker 容器等)。
  • 使用场景
    • 自动化测试:当需要在后台执行大量的浏览器测试时,无头模式可以提高执行速度。
    • 网页抓取(Web Scraping):爬虫程序通常会用无头模式来抓取网页内容,而不需要浏览器界面。
    • CI/CD 流水线:在持续集成或自动化部署中,通常采用无头模式来运行自动化测试,以提高效率。

无头模式的优点:

  1. 性能更高:由于不需要渲染和显示浏览器界面,系统资源占用较少,运行速度较快。
  2. 适用于无图形界面环境:在服务器、虚拟机、容器(如 Docker)等没有图形界面的环境中,可以通过无头模式运行浏览器。
  3. 更适合批量任务:例如自动化测试、网页抓取等任务,因为这些任务通常不需要人工交互,且需要高效处理大量页面。

无头模式的缺点:

  1. 无法直接查看页面:在调试时如果出现问题,无法通过浏览器的界面进行直观检查。
  2. 可能存在兼容性问题:某些功能或页面的行为在有头模式和无头模式下可能有所不同,尤其是与页面渲染和交互有关的复杂功能。

总结

  • 有头模式:浏览器正常显示图形界面,适用于需要人工交互或调试的场景。
  • 无头模式:浏览器不显示图形界面,适用于后台任务,如自动化测试、网页抓取等,通常可以提高性能和效率。

你可以根据实际需求来选择使用哪种模式。如果是自动化测试且不需要查看页面细节,推荐使用无头模式;如果是调试或需要人工交互,则应该使用有头模式。

节点说明

  • 页面加载超时时间,单位为毫秒
  • 元素获取超时时间,单位为毫秒
  • URL:起始地址
  • 节点执行完毕后,会产生resp 类型为SeleniumResponse的变量

 SeleniumResponse 属性

字段名称字段类型字段描述
htmlString页面HTML
jsonJSONObject/JSONArray内容转json结果
cookiesMap<String,String>cookies
urlString当前页面的URL
titleString当前页面的标题

SeleniumResponse 方法

switchTo

参数名描述可否为空
index/iframeName/WebElement要切换的iframe
${resp.switchTo(index)}

TIP

返回值类型:SeleniumResponse

switchToDefault

切换至默认,即从iframe里切换回来

${resp.switchToDefault()}

selector

参数名描述可否为空
cssSelector要获取的cssSelector

TIP

返回值类型:WebElement

  • 获取页面上的第一个div
${resp.selector('div')}

selectors

参数名描述可否为空
cssSelector要获取的cssSelector

TIP

返回值类型:WebElements

  • 获取页面上的所有div
${resp.selectors('div')}

xpath

参数名描述可否为空
xpath要获取的xpath

TIP

返回值类型:WebElement

  • 获取页面上的第一个div
${resp.xpath('//div')}

xpaths

参数名描述可否为空
xpath要获取的xpath

TIP

返回值类型:WebElements

  • 获取页面上的所有div
${resp.xpaths('//div')}

executeScript

参数名描述可否为空
scriptjs脚本
List<Object>参数

TIP

返回值类型:Object

  • 执行js
${resp.executeScript('return "hello spider-flow-" + arguments[0];',['selenium'])}

quit

  • 退出浏览器
${resp.quit()}

 

toUrl

参数名描述可否为空
url要跳转的url
  • 跳转到百度
${resp.toUrl('https://www.baidu.com')}

 

loadCookies

  • 将cookie加载至cookieContext中,以便后续自动管理cookie
${resp.loadCookies()}

WebElement 方法

html

TIP

返回值类型:String

  • 获取节点的html
${elementVar.html()}

text

TIP

返回值类型:String

  • 获取节点的text
${elementVar.text()}

 

attr

TIP

返回值类型:String

  • 获取节点的href属性
${elementVar.attr('href')}

 

selector

参数名描述可否为空
cssSelector要获取的cssSelector

TIP

返回值类型:WebElement

  • 获取该节点下的第一个div
${elementVar.selector('div')}

  

selectors

参数名描述可否为空
cssSelector要获取的cssSelector

TIP

返回值类型:WebElements

  • 获取获取该节点下的所有div
${elementVar.selectors('div')}

xpath

参数名描述可否为空
xpath要获取的xpath

TIP

返回值类型:WebElement

  • 获取获取该节点下的第一个div
 
  1. ${elementVar.xpath('//div')}

xpaths

参数名描述可否为空
xpath要获取的xpath

TIP

返回值类型:WebElements

  • 获取获取该节点下的所有div
​​​​​​​${elementVar.xpaths('//div')}

 

screenshot

TIP

返回值类型:byte[]

  • 对该节点进行截图
${elementVar.screenshot()}

click

TIP

返回值类型:WebElement

  • 对该节点进行点击
${elementVar.click()}

sendKeys

TIP

返回值类型:WebElement

  • 对该节点进行模拟按键
${elementVar.sendKeys('hello spider-flow')}

clickAndHold

release

move

参数名描述可否为空
offset_xoffset x
offset_yoffset y

TIP

在该节点上模拟鼠标移动,当offset_x和offset_y为空时,则模拟鼠标移动到该节点上

doubleClick

pause

perform

TIP

以上6个方法是配套使用,调用perform时才是真正执行动作

  • 模拟鼠标移动到该节点上,等待500ms在点击,等待500ms在移动,最后释放(模拟拖拽滑块条)
${elementVar.move().pause(500).clickAndHold().pause(500).move(200,0).release().perform()}

WebElements 方法

html

TIP

返回值类型:List<String>

  • 获取节点的html
${elementsVar.html()}

text

TIP

返回值类型:List<String>

  • 获取节点的text
${elementsVar.text()}

attr

TIP

返回值类型:List<String>

  • 获取节点的href属性
${elementsVar.attr('href')}

selector

参数名描述可否为空
cssSelector要获取的cssSelector

TIP

返回值类型:WebElement

  • 获取该节点下的第一个div
${elementsVar.selector('div')}

selectors

参数名描述可否为空
cssSelector要获取的cssSelector

TIP

返回值类型:WebElements

  • 获取获取该节点下的所有div
${elementsVar.selectors('div')}

xpath

参数名描述可否为空
xpath要获取的xpath

TIP

返回值类型:WebElement

  • 获取获取该节点下的第一个div
${elementsVar.xpath('//div')}

xpaths

参数名描述可否为空
xpath要获取的xpath

TIP

返回值类型:WebElements

  • 获取获取该节点下的所有div
${elementsVar.xpaths('//div')}

相关文章:

SpiderFlow平台v0.5.0之引入selenium插件

引入selenium插件 首先到码云下载插件点击下载​编辑到本地并导入到工作空间或安装到maven库在spider-flow/spider-flow-web/pom.xml中引入插件 <!-- 引入selenium插件 --> <dependency><groupId>org.spiderflow</groupId><artifactId>spider-…...

git push命令

git push 常用命令 1. 拉取远程仓库最新数据 使用 git fetch git fetch作用&#xff1a; 获取远程仓库的最新数据&#xff08;包括分支、标签等&#xff09;&#xff0c;但不会修改本地工作目录。 结果&#xff1a; 仅更新远程分支&#xff08;如 origin/main&#xff09;的…...

洛谷P1161

开灯 - 洛谷 代码区&#xff1a; #include<stdio.h> int ans[2000005]{1}; //1为关 int main(){int n;scanf("%d",&n);double arry[n][2];//此处最好用双精度浮点数&#xff0c;单精度浮点数的精确度够高对于此题来说&#xff0c;第一次没全对就是因为精度…...

Python脚本自动发送电子邮件

要编写一个Python脚本来自动发送电子邮件&#xff0c;你可以使用smtplib库来处理SMTP协议&#xff0c;以及email库来构建邮件内容。 安装必要的库 通常情况下&#xff0c;smtplib和email库是Python标准库的一部分&#xff0c;因此不需要额外安装。如果你使用的是较旧的Python版…...

vscode的安装与使用

下载 地址&#xff1a;https://code.visualstudio.com/ 安装 修改安装路径&#xff08;不要有中文&#xff09; 点击下一步&#xff0c;创建桌面快捷方式&#xff0c;等待安装 安装中文插件 可以根据自己的需要安装python和Jupyter插件...

sparkRDD教程之必会的题目

1.前期准备 &#xff08;1&#xff09;看看上一期的博客&#xff0c;最好跟着上一期的博客把sparkRDD的基本命令给熟练掌握后&#xff0c;再来做这篇文章的任务。 上一期的博客&#xff1a;sparkRDD教程之基本命令-CSDN博客 &#xff08;2&#xff09;新建文件task6.scala …...

Unity 2d描边基于SpriteRender,高性能的描边解决方案

目标 以Unity默认渲染管线为例&#xff0c;打造不需要图片内边距&#xff0c;描边平滑&#xff0c;高性能的描边解决方案 前言 在2d游戏中经常需要给2d对象添加描边&#xff0c;来突出强调2d对象 当你去网上查找2d描边shader&#xff0c;移植到项目里面&#xff0c;大概率会…...

信凯科技业绩波动明显:毛利率远弱行业,资产负债率偏高

《港湾商业观察》施子夫 1月8日&#xff0c;深交所官网显示&#xff0c;浙江信凯科技集团股份有限公司&#xff08;以下简称“信凯科技”&#xff09;主板IPO提交注册。 自2022年递交上市申请&#xff0c;信凯科技的IPO之路已走过两年光景&#xff0c;尽管提交注册&#xff0…...

js基础---var与let的区别以及const的使用

js基础—var与let的区别以及const的使用 var与let的区别 在较旧的JavaScript&#xff0c;使用关键字var来声明变量&#xff0c;而不是let。var现在开发中一般不再使用它&#xff0c;只是我们可能再老版程序中看到它。let的出现为了解决var的一些问题。 var 声明存在以下三种问…...

用css和html制作太极图

目录 css相关参数介绍 边距 边框 伪元素选择器 太极图案例实现、 代码 效果 css相关参数介绍 边距 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style>*{margin: 0;padding: 0;}div{width: …...

OJ12:160. 相交链表

目录 题目思路分析代码展示 题目 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 示例 1&#xff1a; 输入&#xff1a;intersectVal 8, listA [4,1,8,4,5], listB [5,…...

软件工程和项目管理领域 - CMMI 极简理解

CMMI 概述 CMMI 全称为 Capability Maturity Model Integration&#xff0c;即能力成熟度模型集成 CMMI 是由美国卡内基梅隆大学软件工程研究所&#xff08;SEI&#xff09;开发的一套综合性管理模型 CMMI 是一种用于评估和改进组织在软件开发和维护方面过程能力的国际标准 …...

C# 线程基础之 线程同步

线程同步的手段很多 lock 是通过内存索引块 0 1 切换 进行互斥的实现 互斥量 信号量 事件消息 其实意思就是 一个 标记量 通过这个标记 来进行类似的互斥手段 具体方式的分析 代码在后 1.互斥量 Mutex 作用 非常类似lock 一个Mutex 名称来代替 lock的引用对象 2.信号量 Semaph…...

[c语言日寄]c语言也有“回”字的多种写法——整数交换的三种方式

大家好啊&#xff0c;在今天的快乐刷题中&#xff0c;我们遇到了这样一道题目&#xff1a; 题目 写出 三种不同方式的 交换两个整数变量的 函数 交换变量的三种解法 常规方式 想要交换两个变量很简单&#xff0c;第一种方式就是新建一个临时变量&#xff0c;具体流程如下&…...

RocketMQ 知识速览

文章目录 一、消息队列对比二、RocketMQ 基础1. 消息模型2. 技术架构3. 消息类型4. 消费者类型5. 消费者分组和生产者分组 三、RocketMQ 高级1. 如何解决顺序消费和重复消费2. 如何实现分布式事务3. 如何解决消息堆积问题4. 如何保证高性能读写5. 刷盘机制 &#xff08;topic 模…...

优化 Azure Synapse Dedicated SQL Pool中的 SQL 执行性能的经验方法

在 Azure Synapse Dedicated SQL Pool中优化 SQL 执行涉及了解底层体系结构&#xff08;例如分布和分区&#xff09;、查询优化&#xff08;例如避免不必要的子查询和联接&#xff09;&#xff0c;以及利用具体化视图和 PolyBase 等工具进行高效数据加载。 1.有效使用分布和分…...

详解英语单词“pro bono”:公益服务的表达(中英双语)

中文版 详解英语单词“pro bono”&#xff1a;公益服务的表达 一、词义解释 “Pro bono” 是一个源自拉丁语的短语&#xff0c;完整表达为 “pro bono publico”&#xff0c;意思是“为了公众利益”&#xff08;for the public good&#xff09;。在现代英语中&#xff0c;它…...

16. C语言 字符串详解

本章目录: 前言C 字符串的基础概念字符串的定义字符串的内存表示 常见的字符串操作函数示例代码 深入探讨字符串长度计算strlen 与 sizeof 的区别 字符串操作的注意事项**1. 字符数组的大小**2. 字符数组和字符指针的区别3. 使用安全函数 字符串的遍历与格式化输出**遍历字符串…...

使用Buildroot开始嵌入式Linux系统之旅-3

文章目录 at91bootstrap操作教程修改at91bootstrap具体配置重新编译at91bootstrap U-Boot操作教程修改U-Boot具体配置重新编译U-Boot Linux Kernel操作教程修改Linux Kernel具体配置重新编译Linux Kernel buildroot操作进阶生成图形化软件模块依赖关系查看具体软件模块依赖关系…...

[免费]SpringBoot+Vue新能源汽车充电桩管理系统【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的SpringBootVue新能源汽车充电桩管理系统&#xff0c;分享下哈。 项目视频演示 【免费】SpringBootVue新能源汽车充电桩管理系统 Java毕业设计_哔哩哔哩_bilibili 项目介绍 随着信息化时代的到来&#xff0…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

如何应对敏捷转型中的团队阻力

应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中&#xff0c;明确沟通敏捷转型目的尤为关键&#xff0c;团队成员只有清晰理解转型背后的原因和利益&#xff0c;才能降低对变化的…...

c# 局部函数 定义、功能与示例

C# 局部函数&#xff1a;定义、功能与示例 1. 定义与功能 局部函数&#xff08;Local Function&#xff09;是嵌套在另一个方法内部的私有方法&#xff0c;仅在包含它的方法内可见。 • 作用&#xff1a;封装仅用于当前方法的逻辑&#xff0c;避免污染类作用域&#xff0c;提升…...

MySQL的pymysql操作

本章是MySQL的最后一章&#xff0c;MySQL到此完结&#xff0c;下一站Hadoop&#xff01;&#xff01;&#xff01; 这章很简单&#xff0c;完整代码在最后&#xff0c;详细讲解之前python课程里面也有&#xff0c;感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...