爬虫 selenium

news2024/11/25 16:22:04

爬虫 selenium

【一】介绍

【1】说明

  • Selenium是一款广泛应用于Web应用程序测试的自动化测试框架

    • 它可以模拟用户再浏览器上的行为
    • 对Web应用进行自动化测试
  • 主要作用:

    • 浏览器控制:启动、切换、关闭不同浏览器
    • 元素定位于操作:通过CSS选择器、Xpath等定位方式定位元素位置
    • 网页操作和内容获取:打开、刷新网页、获取URL、获取网页源码、截图、元素定位
    • 测试功能:测试Web应用程序的功能和性能,例如测试表单验证、等待Ajax请求完成操作
    • 测试兼容性:测试应用程序是否能很好的运行在不同浏览器、不同操作系统上

【2】安装引入

  • 安装
pip install selenium

【3】驱动下载

  • win11自带浏览器是microsoft edge
  • 这是官网驱动下载地址
    • https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
  • 根据浏览器版本进行驱动下载

在这里插入图片描述

  • chrome驱动下载地址
    • Chrome for Testing availability (googlechromelabs.github.io)

【4】简单示例

import os
import time
from selenium import webdriver
from selenium.webdriver.edge.service import Service

# 驱动位置
browser_path = os.path.join(os.path.dirname(__file__), 'msedgedriver.exe')
# 需要使用Service对象传递位置,要不然第一运行程序很慢,要等待查找
ser = Service(browser_path)
# 根据驱动选和浏览器进行选择
browser = webdriver.Edge(service=ser)

# 打开网页
browser.get("http://www.baidu.com")
# 等待10秒
time.sleep(10)
# 关闭浏览器
browser.quit()

【二】浏览器操作

【1】基础操作

(1)指定驱动

  • 需要使用Service对象指定驱动位置
    • 要不然第一运行程序很慢
    • 要等待查找程序慢慢查找
from selenium.webdriver.edge.service import Service
# 驱动位置
browser_path = os.path.join(os.path.dirname(__file__), 'msedgedriver.exe')
# 需要使用Service对象指定驱动位置
ser = Service(browser_path)
# 根据驱动选和浏览器进行选择
browser = webdriver.Edge(service=ser)

(2)基础操作

  • 常用
    • browser.get(url)访问指定网址
    • browser.maximize_window()最大化浏览器
    • browser.current_url浏览器当前网址
    • browser.page_source网页源码
    • browser.close()关闭当前窗口
    • browser.quit()关闭浏览器实例
  • 窗口(选项卡):
    • browser.window_handles:所有选项卡列表,每个都是24位字符串
    • browser.execute_script(“window.open();”):打开一个新的选项卡
    • browser.switch_to.window(browser.window_handles[-1]):切换选项卡,切换到最新打开的选项卡
  • 其他
    • browser.set_window_size(width, height):设置浏览器大小(宽, 高)
    • browser.forward():浏览器前进
    • browser.forward():浏览器前进
    • browser.title:浏览器标题
    • browser.name:浏览器名称

(3)八大选择器

  • 需要导入标签定位工具
from selenium.webdriver.common.by import By
  • browser.find_element(By.ID, value)
    • 通过ID查找
  • browser.find_element(By.NAME, value)
    • 通过Name属性查找
  • browser.find_element(By.CLASS_NAME, value)
    • 通过class属性查找
  • browser.find_element(By.TAG_NAME, value)
    • 通过标签名查找
  • browser.find_element(By.LINK_TEXT, value)
    • 通过链接(a标签)文字进行精确定位
  • browser.find_element(By.PARTIAL_LINK_TEXT, value)
    • 通过链接(a标签)文字进行模糊定位
  • browser.find_element(By.XPATH, value)
    • 通过XPath表达式进行定位
  • browser.find_element(By.CSS_SELECTOR, value)
    • 通过css选择器定位

(4)元素操作

  • 首先通过选择器拿到元素

    • tag =  browser.find_element(By.选择器, value)
      tag =  browser.find_elements(By.选择器, value)
      
  • 常用

    • tag.text:获取标签的文本内容
    • tag.get_attribute(key):根据属性名获取属性值
    • tag.click():对标签进行点击操作
    • tag.clear():清空可输入标签内的数据
    • tag.send_keys(data):向标签(input、textarea … …)内输入数据
    • tag.submit():对标签进行提交操作
    • tag.screenshot(‘1.png’):对标签元素进行截图
  • 其他:

    • tag.id:selenium内部使用的id
    • tag.get_property(key):不是所有的 WebDriver 都支持,推荐使用get_attribute(key)
    • tag.location:获取坐标位置{‘x’: 630, ‘y’: 2121}
    • tag.location_once_scrolled_into_view:滚动页面到指定元素的位置,底部对齐,可输出坐标位置还是字典格式
    • tag.size:元素的大小{‘height’: 36, ‘width’: 80}
    • tag.tag_name:获取标签的标签名
    • tag.is_selected():判断元素是否被选中
    • tag.is_enabled():判断元素是否可编辑
    • tag.is_displayed:判断元素是否演示
    • tag._upload(filename):上传文件
    • tag.value_of_css_property(‘color):获取的属性值,这个就是获取颜色属性rgba(57, 81, 179, 1)

【2】页面等待

(1)为什么要等待

  • 放置频率过高,对别人的服务器不好
  • 等待页面的标签元素加载

(2)等待的方法

  • 强制等待(无条件等待)

    • 使用time模块中的sleep方法
  • 隐式等待

    • 通过browser.implicitly_wait(time_to_wait=2)
    • 设置的是WebDriver在整个会话期间等待元素加载到dom的时间,全局的配置
    • 超过指定时间任然未找到将报错
  • 显示等待(智能等待)

    • 针对指定元素指定等待时间

    • from selenium.webdriver.common.by import By
      from selenium.webdriver.support.ui import WebDriverWait
      from selenium.webdriver.support import expected_conditions as EC
      
      # 等待元素出现
      wait = WebDriverWait(browser, 10, 0.5)
      wait.until(EC.presence_of_element_located((By.ID, 'id_value')))
      
    • WebDriverWait(浏览器, 等待时间, 查找频率(默认0.5s))

    • 超出时间也会报错

【3】动作链

(1)什么是动作链

  • 动作链是一种用于模拟复杂用户交互操作的功能

    • 鼠标、键盘操作等
  • 导入动作链类ActionChains

from selenium.webdriver.common.action_chains import ActionChains
  • 导入键盘类Keys
from selenium.webdriver.common.keys import Keys

(2)常用鼠标、键盘操作

  • 鼠标(鼠标操作最后一定要perform)
    • context_click():右击
    • double_click():双击
    • double_and_drop():拖拽
    • move_to_element():悬停
    • perform():执行
  • 键盘(键盘操作可以直接使用
    • send_keys(Keys.BACK_SPACE):删除键
    • send_keys(Keys.SPACE):空格键
    • send_keys(Keys.TAB):制表键
    • send_keys(Keys.ESCAPE):回退键
    • send_keys(Keys.ENTER):回车键
    • send_keys(Keys.CONTROL, ‘a’):全选
    • send_keys(Keys.CONTROL, ‘c’):复制
    • send_keys(Keys.CONTROL, ‘v’):粘贴
    • send_keys(Keys.CONTROL, ‘x’):剪切
    • send_keys(Keys.F1):键盘F1
  • 事件监听
    • click(on_element=None) :左键点击
    • click_and_hold(on_element=None) :单击左键不松开
    • context_click(on_element=None):右键点击
    • double_click(on_element=None):双击左键
    • drag_and_drop(source,target):拖拽某个元素
    • drag_and_drop_by_offset(source,xoffset,yoffset):拖拽并移动指定像素
    • key_down(value,element=None):按下某个键盘
    • key_up(value, element=None):松开键盘上的某个键
    • move_by_offset(xoffset, yoffset):移动指定像素
    • move_to_element(to_element):移动到指定元素
    • move_to_element_with_offset(to_element, xoffset, yoffset):移动到指定元素的位置(距元素左上角)
    • pause(seconds):暂停所有输入,指定时间
    • perform():执行所有操作
    • reset_action():结束已经存在的操作并重置
    • release(on_element=None):在某个元素位置松开鼠标
    • send_keys(*keys_to_send):发送某个键或文本到当前焦点的元素
    • send_keys_to_element(element, *keys_to_send):发送某个键或文本到指定元素

【4】动作链示例

(1)搜狗输入

  • 实际上不用动作链更方便,这里为了演示
import time

from selenium import webdriver
from selenium.webdriver.edge.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys

service = Service('.\msedgedriver.exe')
browser = webdriver.Edge(service=service)

browser.get("https://www.sogou.com/")
browser.maximize_window()
time.sleep(1)

# 创建动态链实例
action = ActionChains(browser)
# 找到输入文本框
input_elm = browser.find_element(By.XPATH, '//*[@id="query"]')
input_elm.send_keys("周润发")  # 输入文本
# 搜索按钮
search_ele = browser.find_element(By.XPATH, '//*[@id="stb"]')
action.move_to_element(search_ele).click().perform()  # 必须要perform

# 等待3s
time.sleep(3)

# 从新找到输入文本框
input_elm = browser.find_element(By.XPATH, '//*[@id="upquery"]')
# input_elm.clear() # 简单直接
input_elm.send_keys(Keys.CONTROL, "a")  # 复杂
time.sleep(0.5)
input_elm.send_keys(Keys.BACK_SPACE)
time.sleep(0.5)
input_elm.send_keys('周星驰')
time.sleep(0.5)

# 搜索按钮
search_ele = browser.find_element(By.XPATH, '//*[@id="searchBtn"]')
action.click(search_ele).perform() # 一定要perform

time.sleep(2)
browser.close()
browser.quit()

(2)拖拽标签滑动

  • 测试网址:http://sahitest.com/demo/dragDropMooTools.htm
import time

from selenium import webdriver
from selenium.webdriver.edge.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys

service = Service('.\msedgedriver.exe')
browser = webdriver.Edge(service=service)

browser.get('http://sahitest.com/demo/dragDropMooTools.htm')
browser.maximize_window()
time.sleep(1)

# 获取元素
source_div = browser.find_element(By.XPATH, '//*[@id="dragger"]')
target_div1 = browser.find_element(By.XPATH, "/html/body/div[2]")
target_div2 = browser.find_element(By.XPATH, "/html/body/div[3]")
target_div3 = browser.find_element(By.XPATH, "/html/body/div[4]")
target_div4 = browser.find_element(By.XPATH, "/html/body/div[5]")

# 实例化动作链
action = ActionChains(browser)
# 拖拽方式一: 直接drag_and_drop
time.sleep(1)
action.drag_and_drop(source_div, target_div1).perform()
# 拖拽方式二:先click_and_hold,然后move_to_element,再然后release
time.sleep(1)
action.click_and_hold(source_div).move_to_element(target_div2).release().perform()
# 拖拽方式三:先计算偏移量,然后drag_and_drop_by_offset
time.sleep(1)
x = target_div3.location['x'] - source_div.location['x']
y = target_div3.location['y'] - source_div.location['y']
action.drag_and_drop_by_offset(source_div, x, y).perform()
# 拖拽方式四:先click_and_hold,然后到目标位置release
time.sleep(1)
action.click_and_hold(source_div).release(target_div4).perform()

time.sleep(2)
browser.close()
browser.quit()

(3)框架(frame)内拖动标签

  • 测试网址:菜鸟教程在线编辑器 (runoob.com)
    • 无法直接操作
    • 需要先切换到指定框架内
import random
import time

import selenium.common.exceptions
from selenium import webdriver
from selenium.webdriver.edge.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys

service = Service('.\msedgedriver.exe')
browser = webdriver.Edge(service=service)
browser.maximize_window()

browser.get('https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
time.sleep(2)

# 根据frame的id进行切换
browser.switch_to.frame('iframeResult')
# 获取元素标签
source_div = browser.find_element(By.XPATH, '//*[@id="draggable"]')
target_div = browser.find_element(By.XPATH, '//*[@id="droppable"]')
# 实例动作链对象
action = ActionChains(browser)
# 计算需要移动的偏移量
x = target_div.location['x'] - source_div.location['x']
try:
    while x:
        m = min(random.randint(1, x), 30)
        action.drag_and_drop_by_offset(source_div, m, 0).perform()
        x -= m
        time.sleep(random.randint(50, 150) / 1000)
except selenium.common.exceptions.UnexpectedAlertPresentException:
    pass

time.sleep(2)
browser.close()
browser.quit()

【5】执行JS代码

(1)需求何来

  • 前端显示受限
  • 页面滚动条无法通过元素获取
  • 通过执行JS代码,甚至还可以修改页面参数

(2)使用方法

  • 打开新的页面
browser.execute_script("window.open()")
browser.switch_to.window(browser.window_handles[-1])
browser.get("http://baidu.com")
  • 滚动到页面底部
browser.execute_script("window.scrollTo(0, document.body.scrollHeight)")
  • 点击元素
next_url = browser.find_element(By.XPATH, '//*[@id="sogou_next"]')
script_str = 'arguments[0].click()'
browser.execute_script(script_str, next_url)
  • 输入文本
input_div = browser.find_element(By.XPATH, '//*[@id="upquery"]')
script_str = 'arguments[0].value = arguments[1]'
browser.execute_script(script_str, input_div, '周杰伦')
  • 获取元素属性
element = browser.find_element(By.XPATH, '//*[@id="searchBtn"]')
script_str = 'return arguments[0].getAttribute("value");'
attribute_value = browser.execute_script(script_str, element)
print(attribute_value)  # 搜狗搜索
  • 拖动元素
    • 速度过快,还是使用动作链
source_div = browser.find_element(By.XPATH, '')
target_div = browser.find_element(By.XPATH, '')
script_str = '''
    var source = arguments[0], target = arguments[1];
    var offsetX = target.getBoundingClientRect().left - source.getBoundingClientRect().left;
    var offsetY = target.getBoundingClientRect().top - source.getBoundingClientRect().top;
    var event = new MouseEvent('mousedown', { bubbles: true, cancelable: true, view: window });
    source.dispatchEvent(event);
    event = new MouseEvent('mousemove', { bubbles: true, cancelable: true, view: window, clientX: offsetX, clientY: offsetY });
    source.dispatchEvent(event);
    event = new MouseEvent('mouseup', { bubbles: true, cancelable: true, view: window });
    source.dispatchEvent(event);
'''
browser.execute_script(script_str, source_div, target_div)
  • 隐藏或伪装浏览器自动化
browser.execute_script("Object.defineProperties(navigator,{webdriver:{get:()=>undefined}})")

【6】options

(1)介绍

  • 无头浏览器是一种没有图形界面(GUI)的的网络浏览器
  • 他通过在内存中渲染页面,然后将结果发送回请求它的用户或程序来实现对网络的访问,而不会在屏幕上显示网页
  • 优点
    • 执行速度快、减少干扰、资源消耗低、易于集成、应用范围广
  • 缺点
    • 不能完全模拟用户真实行为、不适用于需要页面渲染验证的场景、调试困难

(2)页面渲染机制

  1. 解析HTML,构建DOM树
  2. 解析CSS,生成CSSOM树
  3. 合并DOM树和CSSOM树,生成渲染树
  4. 根据渲染树进行布局
  5. 调用GPU绘制渲染树,合并图层,显示在屏幕上
  • 无头浏览器跳过了后面的三个步骤

(2)如何使用

  • 无头浏览器有时还是需要指定窗口大小的
    • 模拟不同设备大小
    • 网页渲染需要
    • 截图一致性
from selenium.webdriver.edge.options import Options
options = Options()
# 指定窗口分辨率
options.add_argument("window-size=1920x1080")
# 隐藏滚动条,应对特殊界面
options.add_argument('--hide-scrollbars')
# 启用无头浏览器
options.add_argument('--headless')
# 不加载图片,提升速度
options.add_argument('blink-settings=imagesEnabled=false')
# 禁用GPU加速
options.add_argument('--disable-gpu')
# 添加IP代理 proxy=f"http://{ip}:{port}"
options.add_argument(f'--proxy-server={proxy}') 
# 隐身模式(无痕模式)
options.add_argument('--incognito')  
# 设置请求头的User-Agent
options.add_argument('--user-agent=""')  
# 浏览器最大化
options.add_argument('--start-maximized')  
# 设置中文
options.add_argument('lang=zh_CN.UTF-8')  
  • 去除自动化控制的设置
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
  • 示例
    • 百度可以
    • 搜狗不行
import time
from selenium import webdriver
from selenium.webdriver.edge.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.edge.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

edge_options = Options()
# 指定窗口分辨率
edge_options.add_argument("window-size=1920x1080")
# 隐藏滚动条,应对特殊界面
edge_options.add_argument('--hide-scrollbars')
# 启用无头浏览器
edge_options.add_argument('--headless')
# 不加载图片,提升速度
edge_options.add_argument('blink-settings=imagesEnabled=false')
# 规避bug
edge_options.add_argument('--disable-gpu')

service = Service('.\msedgedriver.exe')
browser = webdriver.Edge(service=service, options=edge_options)
browser.maximize_window()

browser.get('https://www.baidu.com/')
time.sleep(2)

element = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="su"]')))
script_str = 'return arguments[0].getAttribute("value");'
attribute_value = browser.execute_script(script_str, element)
print(attribute_value)  # 百度一下

time.sleep(1)
browser.close()
browser.quit()

【7】cookie操作

(1)常用方法

  • browser.get_cookies():获取当前页面cookies,是列表套字典
  • browser.add_cookie(cookie_dict):添加cookie
  • browser.delete_cookies(name):根据name删除指定cookie
  • browser.delete_all_cookies():删除所有的cookie

(2)查看add_cookie源码注释

"""
Adds a cookie to your current session.

:Args:
 - cookie_dict: A dictionary object, with required keys - "name" and "value";
    optional keys - "path", "domain", "secure", "httpOnly", "expiry", "sameSite"

:Usage:
    ::
        driver.add_cookie({'name' : 'foo', 'value' : 'bar'})
        driver.add_cookie({'name' : 'foo', 'value' : 'bar', 'path' : '/'})
        driver.add_cookie({'name' : 'foo', 'value' : 'bar', 'path' : '/', 'secure' : True})
        driver.add_cookie({'name' : 'foo', 'value' : 'bar', 'sameSite' : 'Strict'})
"""
  • cookie_dict以字典的形式传入
    • 字典中必须有name和value两个键
    • 可选的键有:“path”, “domain”, “secure”, “httpOnly”, “expiry”, “sameSite”
  • 键名的含义
    • name:cookie的名称。唯一标识符,区分不同的cookie
    • value:cookie对应的值
    • domain:cookie适用的域名。定义哪些域名可以接收和发送cookie
    • expiry或max-age:cookie的过期时间
    • path:cookie适用的URL路径
    • httpOnly:一个标识,指示cookie是否只能通过HTTP(S)协议访问,而不能通过客户端脚本(如javascript)访问
    • secure:一个标识,指示cookie是否只能通过安全的HTTPS连接传输
    • sameSite:定义cookie的sameSite属性,控制何时发送cookie,有助于放置跨站请求伪造(csrf)攻击,有三个值
      • Strict:仅当请求来自同一站点才发送cookie
      • Lax:在导航到目标站点(即链接点击)或顶级导航到相同站点时发送cookie
      • None:浏览器始终发送cookie,不考虑请求的站点。
        • 这通常和Secure属性一起使用,以增强安全性

(3)使用方法

# 保存cookies
cookies = browser.get_cookies()
with open(cookie_path, 'wt', encoding='utf8') as fp:
	json.dump(cookies, fp=fp)
# 添加cookie
with open(cookie_path, 'rt', encoding='utf8') as fp:
	cookies = json.load(fp=fp)
for cookie in cookies:
	browser.add_cookie(cookie)
# 转为requets中的cookies字典
with open(cookie_path, 'rt', encoding='utf8') as fp:
	cookies = json.load(fp=fp)
requests_cookies = {cookie.get('name'):cookie.get('value') for cookie in cookies}    
# 转换为headers中的cookie
from urllib.parse import quote  # 用于编码cookie的名称和值  
with open(cookie_path, 'rt', encoding='utf8') as fp:
	cookies = json.load(fp=fp)
headers_cookie = "; ".join([f"{quote(cookie['name'])}={quote(cookie['value'])}" for cookie in cookies])

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

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

相关文章

突破编程_前端_SVG(概述)

1 什么是 SVG SVG,全称可缩放矢量图形(Scalable Vector Graphics),是一种基于 XML(可扩展标记语言)的矢量图像格式。这种图像格式的主要特点是它描述的是矢量图形,而不是基于像素的位图图像。因…

计数排序解读

当我们提及排序算法时,通常会想到冒泡排序、选择排序、插入排序、归并排序和快速排序等经典算法。然而,今天我们要探讨的是一种非比较型整数排序算法——计数排序。计数排序在某些特定场景下表现出色,具有线性的时间复杂度。下面我们将深度剖…

如何看待现在的前端?必备技能和方向?

​ 目录 1. 技术生态丰富 2. 用户体验为中心 3. 跨平台和移动优先 4. 性能和安全性 5. 前端工程化和自动化 6. 服务端渲染和静态站点生成 7. 人工智能和机器学习的融合 总结 发展方向: 必备技能: 当前前端开发领域正在经历快速的发展和变革。…

Three飞线动画(运动轨迹)

效果图 1.初始化场景 onMounted(() > {line() })let index 0; //取索引值的点的位置 let num 20; //从曲线上获取的数量 let points1, newLine1, bufferGeometry1; let points2, newLine2, bufferGeometry2;function line() {} 2.场景中加入一条三维曲线 function line…

Flody算法求解多源最短路问题

Flody算法求解多源最短路问题 蓝桥公园 #include <bits/stdc.h> using namespace std; #define int long long const int N409; int n,m,q,d[N][N]; signed main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);cin>>n>>m>>q;memset(d,0x3f,sizeof…

Linux网卡与IP地址:通往网络世界的通行证

在探索Linux网卡和IP地址的关系之前&#xff0c;我们得先理解Linux网卡是怎么工作的。想象一下&#xff0c;每台计算机都是一个世界&#x1f30e;&#xff0c;而网卡就是连接这些世界的门户&#x1f6aa;。网卡的工作就是接收和发送数据包&#xff0c;就像邮差&#x1f4ec;递送…

在win10上虚拟一个LoongOS系统(类似虚拟机)作为开发环境

文章目录 1.安装1.1.下载这三个东西1.2.安装好qemu。1.3.创建一个启动脚本startup_mate.bat&#xff0c;然后把三部分东西放到一起1.4.然后双击startup.bat就可以启动了。 2.文件的传输2.1.使能虚拟机系统的ssh2.2.连接ssh 3.Qt相关安装Qt安装opencv 1.安装 注意&#xff0c;一…

揭秘操作系统:核心功能与Linux系统解析

1.引言 在先前探讨中&#xff0c;我们了解到计算机主机内部的硬件资源需要一种高效管控手段&#xff0c;由此催生了操作系统的诞生。操作系统&#xff08;Operating System&#xff0c;简称OS&#xff09;&#xff0c;是计算机生态系统中不可或缺的核心组件&#xff0c;以其复杂…

高颜值高性能的开源免费自托管照片和视频备份方案:Immich

Immich&#xff1a;安全存储您的珍贵记忆&#xff0c;高颜值且高性能的自托管照片与视频备份解决方案&#xff0c;让您随时随地无忧回顾美好时光。- 精选真开源&#xff0c;释放新价值。 概览 在数字化时代&#xff0c;我们的照片和视频越来越多&#xff0c;如何安全、有效地备…

DSP笔记12-PWM基础知识及EPWM

PWM pulse width modulation 脉冲宽度调制&#xff0c;宽度可调节的方波脉冲&#xff0c;驱动开关器件&#xff0c; 参数&#xff1a; 1.频率f 1kHz&#xff0c;2kHz开关损耗 2.周期T 3.幅值&#xff0c;高低电平之间电压 gpio输出3.3V&#xff0c;转换成5V高电平输出 4.占…

Vue项目中,使用高级表格vxe-table中的【vxe-grid】动态列之动态插槽

1、首先项目当中得安装了vxe-table // 没有安装的话&#xff0c;可以使用一下命令安装 npm install vxe-table 或 yarn add vxe-table使用示例&#xff1a; import Vue from vue import VXETable from vxe-table import vxe-table/lib/style.cssVue.use(VXETable)2、动态列中动…

苍穹外卖---文件上传-阿里OSS

一&#xff1a;开通阿里云对象存储服务oss,创建bucket&#xff0c;获得密钥 二&#xff1a;在程序中集成上传文件功能 1.连接阿里云OSS对象存储服务器 声明一个配置属性的文件用于传入连接的参数 package com.sky.properties;import lombok.Data; import org.springframewo…

电感在 DC/DC 变换器中的作用及选型指南

消费类应用是现代 DC/DC 变换器需求的主要驱动力。在这类应用中&#xff0c;功率电感主要被用于电池供电设备、嵌入式计算&#xff0c;以及高功率、高频率的 DC/DC 变换器。了解电感的电气特性对于设计紧凑型、经济型、高效率、并具备出色散热性能的系统至关重要。 电感是一种…

AI 对话完善【人工智能】

AI 对话【人工智能】 前言版权开源推荐AI 对话v0版本&#xff1a;基础v1版本&#xff1a;对话数据表tag.jsTagController v2版本&#xff1a;回复中textarea.jsChatController v3版本&#xff1a;流式输出chatLast.jsChatController v4版本&#xff1a;多轮对话QianfanUtilChat…

【分析 GClog 的吞吐量和停顿时间、heapdump 内存泄漏分析】

文章目录 &#x1f50a;博主介绍&#x1f964;本文内容GClog分析以优化吞吐量和停顿时间步骤1: 收集GClog步骤2: 分析GClog步骤3: 优化建议步骤4: 实施优化 Heapdump内存泄漏分析步骤1: 获取Heapdump步骤2: 分析Heapdump步骤3: 定位泄漏对象步骤4: 分析泄漏原因步骤5: 修复泄漏…

linux服务使用./xxx.sh执行脚本命令

设置脚本文件为全权限 chmod 777 xxx.sh直接使用./xxxx.sh即可

go语言学习--4.方法和接口

目录 1.方法 2.接口 2.1结构体类型 2.2具体类型向接口类型赋值 2.3获取接口类型数据的具体类型信息 3.channel 3.1阻塞式读写channel操作 2.3非阻塞式读写channel操作 4.map 4.1插入数据 4.2删除数据 4.3查找数据 4.4扩容 1.方法 方法一般是面向对象编程(OOP)的一…

2万亿训练数据!Stable LM 2-12B加入开源队列

公*众*号&#xff1a;AI疯人院 4月9日&#xff0c;知名大型模型开源平台Stability.ai在其官网上发布了全新的类ChatGPT模型——Stable LM 2 12B。 据了解&#xff0c;Stable LM 2 12B模型拥有120亿个参数&#xff0c;其训练数据涵盖了英语、西班牙语、德语等7种语言的2万亿个…

【MATLAB源码-第179期】基于matlab的64QAM调制解调系统频偏估计及补偿算法仿真,对比补偿前后的星座图误码率。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 在通信系统中&#xff0c;频率偏移是一种常见的问题&#xff0c;它会导致接收到的信号频率与发送信号的频率不完全匹配&#xff0c;进而影响通信质量。在调制技术中&#xff0c;QPSK&#xff08;Quadrature Phase Shift Keyi…

《由浅入深学习SAP财务》:第2章 总账模块 - 2.6 定期处理 - 2.6.2 月末操作:GR/IR重组

2.6.2 月末操作&#xff1a;GR/IR重组 SAP在采购订单收货和发票校验时分别产生凭证&#xff0c;中间采用GR/IR过渡。GR即为收货&#xff0c;IR即为收票。月末&#xff0c;GR/IR的余额根据收货和收票的情况进行判断&#xff0c;转入“应付暂估”或“在途物资”&#xff0c;次月自…