Selenium常用函数介绍
目录
一,元素定位
1.1 cssSeector
1.2 xpath
二,操作测试对象
三,窗口
3.1 案例
3.2 窗口切换
3.3 窗口大小
3.4 屏幕截图
3.5 关闭窗口
四,弹窗
五,等待
六,导航
七,文件上传
八,浏览器参数
一,元素定位
我们常用选择器有两个,cssSelector 和 xpath
1.1 cssSeector
编写该文章时的百度首页如下:
假设我想使用程序获取热搜部分选项中的文字内容,可以先按F12找到对应选项的selector:
如下代码:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
import timeChromIns=ChromeDriverManager().install() #安装驱动,是给这个程序装一个
driver=webdriver.Chrome(service=Service(ChromIns)) #创建谷歌浏览器驱动对象,之后就可以通过这个对象来驱动浏览器
driver.get("https://www.baidu.com") #输入百度网址,要输入完整URL
ret=driver.find_elements(By.CSS_SELECTOR,"#hotsearch-content-wrapper > li:nth-child(1) > a > span.title-content-title")
for i in ret:print(i.text)
driver.quit() #关闭浏览器
cssSelector选择器功能是选中页面中指定的标签的元素,我们以前讲过css的选择器,分为基础选择器和复合选择器:前端学习(2)—— CSS详解与使用_前端css-CSDN博客
1.2 xpath
XML路径语言,可以在XML文件中查找信息,还可以在html中选取节点;xpath使用路径表达式来选择XML文档中的节点
我们也像上面一样复制元素,至是方式选择Xpath:
复制粘贴后就是://*[@id="hotsearch-content-wrapper"]/li[1]/a/span[2] 下面我们来解释下xpath的语法:
- //*:表示获取HTML页面所有的节点
- //[指定节点]:比如 //ul 表示获取HTML页面中所有的ul节点
- /:表示获取一个节点中的直接子节点,比如 //span/input ,表示获取span标签中的input标签,和选择器功能类似
- ..:这个是两个点,表示获取一个节点的父节点
- [@...]:表示实现节点属性的匹配,比如 //*[@id='kw'],表示匹配HTML页面中id属性为kw的节点
然后我们回到我们前面复制的内容,首先是//*,先获取到页面所有节点,然后就是找到对应id属性的内容,百度首页的部分源代码如下,可以看到对应id属性的标签:
然后就是 /li[1],我们把上面内容合并后是这样的:
可以看到有很多li标签,我们找到第一个li标签,然后找到里面的a标签:
然后a标签里面有两个span,我们找到第二个span,这就是我们xpath路径语言找寻目标的语法
虽然我们能手动复制,但我们需要了解xpath的语法,因为后面我们可能需要手动进行修改或编写选择器元素
二,操作测试对象
部分操作测试对象我们前面已经介绍过了
①点击事件
driver.find_element(By.CSS_SELECTOR, "#su").click()
②模拟按键输入
driver.find_element(By.CSS_SELECTOR, "#kw").send_keys("你好")
③清楚文本内容
driver.find_element(By.CSS_SELECTOR, "#kw").clear() #如果不清除连续的sendkeys,是直接拼接在后面的
④获取文本信息
使用CSS选择器和使用xpath获取文本信息我们标题一已经介绍过了这里不再赘述
下面我们尝试获取下百度以西按钮里的“百度一下”这四个字,看看效果:
可以看到打印结果为空,这是因为这是一种特殊情况:元素属性不等于文本信息(span标签中间的内容),我们看下网页源代码:
可以看到“百度一下”这四个字是放在input标签的value属性后面的,是数学值,所以我们需要用获取属性的那个方法 getAttribute("属性名称"),如下代码:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
import timeChromIns=ChromeDriverManager().install() #安装驱动,是给这个程序装一个
driver=webdriver.Chrome(service=Service(ChromIns)) #创建谷歌浏览器驱动对象,之后就可以通过这个对象来驱动浏览器
driver.get("https://www.baidu.com") #输入百度网址,要输入完整URL
ret=driver.find_element(By.CSS_SELECTOR,"#su").get_attribute("value")
print(ret)
driver.quit() #关闭浏览器
⑤获取页面标题的url
三,窗口
注意:这个窗口不是弹窗哦
3.1 案例
我们先看一个案例:假设我要打开百度首页的图片:
浏览器会单独打开一个窗口,然后我们获取一下两个窗口的url和标题,如下代码:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
import timeChromIns=ChromeDriverManager().install() #安装驱动,是给这个程序装一个
driver=webdriver.Chrome(service=Service(ChromIns)) #创建谷歌浏览器驱动对象,之后就可以通过这个对象来驱动浏览器
driver.get("https://www.baidu.com") #输入百度网址,要输入完整URL
print(driver.title)
print(driver.current_url)
driver.find_element(By.CSS_SELECTOR,"#s-top-left > a:nth-child(6)").click()
print(driver.title)
print(driver.current_url)
driver.quit() #关闭浏览器
可以看到程序执行后可以跳转,但是我们两次获取的网页标题和url是一样的,都是百度首页的url,不受百度图片的url,这是因为我们虽然让浏览器打开了一个新的页面,但是程序本身的操作对象还是百度首页而不是百度图片,所以我们需要让程序识别到不同的窗口
3.2 窗口切换
如何让程序识别每一个窗口呢?每个浏览器的每个窗口都有唯一的一个“属性句柄”来表示, 所以我们可以通过句柄来切换,如下代码:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
import timeChromIns=ChromeDriverManager().install()
driver=webdriver.Chrome(service=Service(ChromIns))
driver.get("https://www.baidu.com")
print(driver.title)
print(driver.current_url)
driver.find_element(By.CSS_SELECTOR,"#s-top-left > a:nth-child(6)").click() #获取并点击百度图片
curHandle = driver.current_window_handle #获取当前页面句柄
allHandles = driver.window_handles #获取所有句柄
for handle in allHandles: #遍历所有句柄,第一次循环handle是百度首页,不做处理,第二次handle就是百度图片了,执行切换操作if handle != curHandle:driver.switch_to.window(handle) #切换到当前的handle
print(driver.title)
print(driver.current_url)
driver.quit() #关闭浏览器
注意:
- 测试中很少有在存在多个标签页,然后切换到一个标签页的场景,通常情况下一般会打开两个标签页进行切换测试,更多的则是直接输入URL进行测试
- 如果没有打开新的窗口,而是直接在当前窗口进行了切换,那么不需要进行窗口切换
3.3 窗口大小
这个了解即可,因为在自动化脚本执行过程中一般不关注窗口大小变化,如下代码:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManagerChromeIns = ChromeDriverManager().install() #安装驱动
driver = webdriver.Chrome(service = Service(ChromeIns)) #创建谷歌浏览器对象
driver.get("https://www.baidu.com") #输入网址
driver.maximize_window() #窗⼝最⼩化
driver.minimize_window() #全屏窗⼝
driver.fullscreen_window() #窗口全屏
driver.set_window_size(500, 500)
driver.quit() #关闭浏览器
3.4 屏幕截图
当自动化运行报错时,仅通过终端的错误提示给到的有用信息是有限的,如果有了屏幕截图,能更好的定位问题并解决问题,截图的语句如下:
driver.save_screenshot('./baidu.png') #括号里面的是路径
由于图片给定的名称是固定的,当我们多次运行自动化脚本时,历史图片将被覆盖,所以不能将图片名称给死,我们要想办法让历史的图片文件都是唯一的,可以采用时间戳的办法:
from datetime import datetime
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
import timeChromIns=ChromeDriverManager().install()
driver=webdriver.Chrome(service=Service(ChromIns))
driver.get("https://www.baidu.com")
filename = "autotest-" + datetime.now().strftime('%Y-%m-%d-%H%M%S') + '.png'
driver.save_screenshot('./' + filename)
driver.quit() #关闭浏览器
3.5 关闭窗口
和quit不同的是,我们是要关闭一个窗口,而不是关闭浏览器,如下代码:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
import timeChromIns=ChromeDriverManager().install()
driver=webdriver.Chrome(service=Service(ChromIns))
driver.get("https://www.baidu.com") #打开百度首页
driver.find_element(By.CSS_SELECTOR, "#s-top-left > a:nth-child(6)").click() #打开百度图片
driver.close() #关闭百度首页
time.sleep(3) #三秒后关闭浏览器
driver.quit() #关闭浏览器
四,弹窗
有三种:警告弹窗,确认弹窗,提升弹窗
我们无法在弹窗上找到弹窗的任何元素,所以通过程序点击弹窗出发按钮后,无法再通过程序找到弹窗的元素进而关闭弹唱,必须先处理弹窗后才能定位到页面的元素,所以我们的步骤就是:1,切换到弹窗 2,关闭弹窗(点击确定/取消)
下面是一个简单的html页面,里面有一个按钮,按下可以弹出弹窗:
<div><button onclick="Hello()">打开弹窗</button>
</div>
<script>function Hello(){alert("你好,祝您生活愉快");}
</script>
from datetime import datetime
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
import timeChromIns = ChromeDriverManager().install()
driver = webdriver.Chrome(service=Service(ChromIns))
driver.get("C:/Users/PC/PycharmProjects/hello/hello.html")
driver.find_element(By.CSS_SELECTOR, "body > div > button").click()
time.sleep(3)
alert = driver.switch_to.alert #获取窗口
alert.accept() #确认
#alert.dismiss() #确认弹窗就是确认和取消任选其一,但是警告窗口只有一个确认所以两个都可以
driver.quit()
注,python代码识别Windows的文件路径分隔符“ \ ”时可能会报错,所以复制 hello.html 路径后需要把路径分隔符换成“ / ”
然后对于提示弹窗需要我们输入信息,所以我们需要额外处理:
下面是提示痰喘,需要用到prompt方法:
<div><button onclick="Hello()">打开弹窗</button>
</div>
<script>function Hello(){prompt("你好,今天天气不错!");
}
</script>
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
import timeChromIns = ChromeDriverManager().install()
driver = webdriver.Chrome(service=Service(ChromIns))
driver.get("C:/Users/PC/PycharmProjects/hello/hello.html")
driver.find_element(By.CSS_SELECTOR, "body > div > button").click()
alert = driver.switch_to.alert #切换到弹窗
alert.send_keys("是的呢") #输入到弹窗中
alert.accept() #确认
注意:我们用程序在弹窗上输入信息是不显示的,但是后面我们如果去获取打印时也能打印,说明是输入成功了的
五,等待
①为什么要等待
有时候一个页面可能会有很多图片,比如一些购物网站,而图片一多,页面的加载时间就会变长
而通常,我们代码的执行速度是比页面渲染的时间要快的,所以可能会出现渲染过慢导致自动化程序出现报错,所以我们可以使用selenium的三种等待方法
②强制等待
就是我们前面使用的 time.sleep() ,程序会强制阻塞,等待指定秒数后才继续执行后面的代码,缺点很明显,非常影响运行效率,主要是在调试里使用,正式测试慎用
③隐式等待
是一种智能等待,规定在在查找元素时,在指定时间内循环查找,如果找到代码则继续运行,直到超时还没找到元素才会报错,语法如下:
driver.implicitly_wait(3)
隐等待的作用域是整个脚本的所有元素,就是只要driver对象没有被释放掉,隐式等待就会一直生效,这个生效是针对该driver的每个线性的操作,所以一般定义在程序代码开头
④显示等待
也是一种智能等待,和隐式等待不同,显示等待只作用域单独一行代码,并且实现也比较复杂,表达式如下:
WebDriverWait(driver, sec).until(functions)
driver表示要等待的对象,sec表示要等待的秒数,function表示需要满足的条件,只有在规定时间内满足条件,才会继续执行后续代码,超时则直接报错
function方法有很多,这里只介绍查找元素的方法:
wait = WebDriverWait(driver, 2).until(EC.invisibility_of_element((By.CSS_SELECTOR, "要查找的元素")))
这句代码表示先创建一个显示等待的类,然后调用这个类的until方法,参数也是一个表达式,有很多,上面只是其中一种
显示等待可以处理隐式等待无法处理的问题,比如弹窗alert_is_present(),这个方法就是检查是否出现弹窗
但是注意,显示和隐式不建议一起用,可能会导致不可预测的等待时间
六,导航
主要是四种行为:打开、前进、后退、刷新,打开网页我们就是driver,get(url),下面我们简单概括下后面三个:
driver.find_element(By.CSS_SELECTOR, "kw").send_keys("你好")
driver.back() #后退
driver.forward() #前进
driver.refresh() #刷新页面
七,文件上传
当页面元素发起上传的窗口后,文件窗口同样无法作为页面元素选中,那么该如何定位到窗口并选中文件呢?
其实我们直接使用sedkeys即可,之后后面不再带文字,而是路径信息:
driver.get("本地html文件路径") 来唤起浏览器打开这个html
driver.find_element(By.CSSSELECTOR, "").sendkeys("文件路径+名称")
八,浏览器参数
①设置页面无头模式
程序在后端运行,但是不显示浏览器的页面的表现叫做无头模式,我们前面的都是有头模式,如下代码:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManagerChromeIns = ChromeDriverManager().install() #安装驱动
options = webdriver.ChromeOptions() #获取驱动参数
options.add_argument('--headless') #添加浏览器参数配置,--headless表示无头模式
driver = webdriver.Chrome(service = Service(ChromeIns), options=options) #创建谷歌浏览器对象
driver.get("https://www.baidu.com") #输入网址
print(driver.title)
②设置页面加载策略
一个页面可能有非常多的资源,文字图片甚至视频,假设我们让自动化程序开始运行,但由于页面还没有加载完,所以我们得等待页面完全加载完再点击测试,这样比较耗时间
driver.get() 方法默认是等所有资源全部加载完毕才继续往下执行,但是实际上,只要页面的部分内容加载完后就已经可以执行自动化了,若因为网络或者其它原有导致加载时间过长,就会导致等待超时、找不到元素等问题
设置加载策略代码如下:
options.page_load_strategy = 'eager' #eager表示DOM访问已经准备就绪但诸如图像的其他资源可能仍在加载,normal是等待所有资源就绪,none是完全不会阻塞WebDriver
相关文章:

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...

华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...

力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...

如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...

【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill
视觉语言模型(Vision-Language Models, VLMs),为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展,机器人仍难以胜任复杂的长时程任务(如家具装配),主要受限于人…...

搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...

mac 安装homebrew (nvm 及git)
mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用: 方法一:使用 Homebrew 安装 Git(推荐) 步骤如下:打开终端(Terminal.app) 1.安装 Homebrew…...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...

接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...

STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...