selenium高级应用
常见控件应用
- 复杂的控件操作
- 1.操作Ajax选项
- 2.滑动滑块操作
- WebDriver的特殊操作
- 元素class值包含空格
- property、attribute、text的区别
- 定位动态id
- 截图功能
- 页面截图
- 页面截图,返回截图的二进制数据
- 页面截图,返回base64的字符串
- 截取指定元素。先定位元素,然后截图
- 测试断言失败截图
- 获取焦点元素
- 颜色验证
- JavaScript的应用
- 高亮显示正在被操作的页面元素
- 修改页面元素属性
- 操作页面元素
- 操作滚动条
- 借助JavaScript操作纵向滚动条
- 借助JavaScript操作横向滚动条
- 操作内嵌滚动条
- 引申通过ActionChains 实现滚动条
- 操作span类型元素
- 通过id来定位元素,获取span的文本
- 通过JavaScript修改标签的文本
复杂的控件操作
1.操作Ajax选项
Ajax即Asynchronous JavaScript and XML(异步JavaScript和XML),是指一种创建交互式、快速动态网页应用的网页开发技术。通过在后台与服务器进行少量数据交换,Ajax可以使网页实现异步更新。这意味着Ajax可以在不重新加载整个网页的情况下,对网页的某部分内容进行更新。搜狗搜索的搜索框使用了Ajax。被测地址为https://www.sogou.com/。单击一下搜狗搜索框,切换到搜索框后,会弹出推荐搜索的热词,这个效果就是Ajax效果。
- 通过模拟键盘输入下键(↓)进行选项选择
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from time import sleep
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()
driver.get('https://www.sogou.com/')ele1 = driver.find_element(By.ID,"query")
ele1.click()
sleep(1)
ele1.send_keys(Keys.ARROW_DOWN)
ele1.send_keys(Keys.ARROW_DOWN)
ele1.send_keys(Keys.ARROW_DOWN)
sleep(5)
driver.quit()
- 通过模糊匹配选择选项。
from selenium import webdriver
from time import sleep
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()
driver.get('https://www.sogou.com/')
driver.find_element(By.ID,'query').send_keys('storm')
sleep(1)
sercont = driver.find_element(By.XPATH,'//*[@id="vl"]/div[1]/ul/li[contains(.,"形容词")]').click()
sleep(5)
driver.quit()
上述代码先在搜索框中输入了“storm”,然后从匹配的选项中选择了带有“形容词”字样的选项,再进行搜索操作(搜索“storm+形容词”)。
- 固定选择某一个位置的选项。
Ajax悬浮框的内容会发生变化(根据一定的推荐算法),而某些时候你可能只是想固定选择悬浮框中的某一个选项,如第二项,这时可以参考下面的代码
from selenium import webdriver
from time import sleepdriver = webdriver.Chrome()
driver.get('https://www.sogou.com/')
driver.find_element('id','query').send_keys('storm')
sleep(1)
sercont = driver.find_element('xpath','//*[@id="vl"]/div[1]/ul/li[2]').click() # li[2]选择第2项
sleep(5)
driver.quit()
2.滑动滑块操作
在实际项目中,你可能会遇到以下场景:在某些页面中需要从左到右拖动滑块进行验证,然后才能进行下一步操作。
可以看出,无论是滑块本身,还是滑块所在的框,都是div元素。
- 操作思路
- 定位到滑块。
- 计算滑块框的宽度。
- 然后将滑块向右拖动框的宽度的距离。
from selenium import webdriver
from time import sleep
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()
driver.get('https://passport.ctrip.com/user/reg/home')
driver.find_element(By.XPATH,'//*[@id="agr_pop"]/div[3]/a[2]').click()
sleep(2)
# 获取滑块
slider = driver.find_element(By.XPATH,'//*[@id="slideCode"]/div[1]/div[2]')
# 获取整个滑块框
ele = driver.find_element(By.ID,'slideCode')
# 需要使用到Actions的方法来进行拖动
ActionChains(driver)\.drag_and_drop_by_offset(slider,ele.size['width'], ele.size ['height'])\.perform()
# 这样也行,向右拖动一定的距离,长度是滑块框的宽度
# ActionChains(driver).drag_and_drop_by_offset(slider,ele.size['width'], 0).perform()
sleep(2)
driver.quit()
WebDriver的特殊操作
元素class值包含空格
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>元素class值带空格</title>
</head>
<body>
Please input your name: <input class="hello storm">
</body>
</html>
- 使用空格前面或后面的部分来定位元素
rom selenium import webdriver
from time import sleep
import osdriver = webdriver.Chrome()
html_file = 'File:///' + os.getcwd() + os.sep + 'myhtml7_1.html'
driver.get(html_file)
# 使用空格前面或后面的部分来定位元素
driver.find_element_by_class_name('hello').send_keys('Storm')
sleep(2)
driver.quit()
- 使用CSS来定位元素,空格用“.”代替
from selenium import webdriver
from time import sleep
import osdriver = webdriver.Chrome()
html_file = 'File:///' + os.getcwd() + os.sep + 'myhtml7_1.html'
driver.get(html_file)
# 使用CSS来定位元素,空格用"."代替
driver.find_element_by_css_selector('.hello.storm').send_keys('Storm')
sleep(2)
driver.quit()
property、attribute、text的区别
- get_property就是用来获取元素属性的,目标元素id和name就可以通过该方法获取;
- get_attribute(“value”)就是用来获取文本框中输入的内容的;
- text属性就是元素本身的文字显示;
- “property”是DOM中的属性,是JavaScript里的对象;“attribute”是HTML标签上的特性,它的值只能是字符串。
定位动态id
输入框有id属性,id的值由两大部分构成,前面是“auto-id-”字符,后面是一串数字。当你刷新页面的时候会发现,这串数字会发生变化,这个id就是动态id。
那如何定位动态id元素呢?
- 使用其他方式定位如果该元素有其他唯一属性值,如class name、name等,我们可以使用这些属性来定位。
- 根据相对关系定位根据父子、兄弟相邻节点定位
- 根据部分元素属性定位
XPath提供了3种非常强大的方法来支持定位部分属性值。contains(a, b):如果a中含有字符串b,则返回True,否则返回False。starts-with(a, b):如果a以字符串b开头,则返回True,否则返回False。ends-with(a, b):如果a以字符串b结尾,返回True,否则返回False。
使用contains关键字
from selenium import webdriver
from time import sleepdriver = webdriver.Chrome()
driver.get('https://www.126.com/')
driver.find_element_by_link_text('密码登录').click()
sleep(2)
driver.switch_to.frame(0)
driver.find_element_by_xpath('//input[contains(@id,"auto-id-")]').send_keys('storm')
sleep(2)
driver.quit()
使用starts-with关键字
from selenium import webdriver
from time import sleepdriver = webdriver.Chrome()
driver.get('https://www.126.com/')
driver.find_element_by_link_text('密码登录').click()
sleep(2)
driver.switch_to.frame(0)
driver.find_element_by_xpath('//input[starts-with(@id,"auto-id-")]').send_keys('storm')
sleep(2)
driver.quit()
截图功能
页面截图
截取当前页面,保存成.png图片
from selenium import webdriverdriver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
driver.save_screenshot('a.png') # 截取当前页面,保存到当前目录,保存成.png图片
# driver.get_screenshot_as_file('a.png'),和上面功能相同
driver.quit()
脚本执行后,程序会在脚本所在目录生成一张名为“a.png”的图片。为了避免图片名重复,我们将图片名修改为“脚本名+时间戳+.png”的格式
from selenium import webdriver
import os
import timescript_name = os.path.basename(__file__).split('.')[0] # 获取当前脚本的名称,不包含扩展名
file_name = script_name + '_' + str(time.time()) + '.png' #组合成图片名
# print(file_name)
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
driver.save_screenshot(file_name) # 截取当前页面,保存成".png"图片
driver.quit()
页面截图,返回截图的二进制数据
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
a = driver.get_screenshot_as_png() # 截图,返回截图的二进制数据
print(type(a))
print(a)
driver.quit()
页面截图,返回base64的字符串
截取指定元素。先定位元素,然后截图
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://www.baidu.com/')
driver.find_element_by_id('su').screenshot('d:\\A\\button.png') # 定位元素,然后截图
driver.quit()
测试断言失败截图
这里我们构造一个断言失败的场景:打开百度首页,在搜索框中输入“Storm”,然后断言搜索框中的文字是不是“storm”,因大小写不匹配执行截图操作。
from selenium import webdriverdriver = webdriver.Chrome()
driver.get('http://www.baidu.com/')
driver.find_element_by_id('kw').send_keys('Storm')
if driver.find_element_by_id('kw').text == "storm":pass
else:driver.save_screenshot('d:\\A\\a.png')
driver.quit()
获取焦点元素
当浏览器访问某个页面时,页面中会有默认的焦点元素。例如,我们访问百度首页时,默认的焦点元素是搜索框,即打开百度首页后,光标自动定位在搜索框。这时候我们可以使用“driver.switch_to.active_element”来获取搜索框元素。
from selenium import webdriverdriver = webdriver.Chrome()
driver.get("https://www.baidu.com")
# 获取当前焦点所在元素的attribute信息
id = driver.switch_to.active_element.get_attribute('id')print(id)
driver.quit()
颜色验证
在测试过程中,偶尔会需要验证某事物的颜色。但问题是网络上对颜色的定义可能采用了不同的方式,如HEX、RGB、RGBA、HSLA。如何去判断颜色是否符合预期呢?首先,你需要引入“Color”的包。
from selenium.webdriver.support.color import Color
创建颜色对象
HEX_COLOUR = Color.from_string('#2F7ED8')
RGB_COLOUR = Color.from_string('rgb(255, 255, 255)')
RGB_COLOUR = Color.from_string('rgb(40%, 20%, 40%)')
RGBA_COLOUR = Color.from_string('rgba(255, 255, 255, 0.5)')
RGBA_COLOUR = Color.from_string('rgba(40%, 20%, 40%, 0.5)')
HSL_COLOUR = Color.from_string('hsl(100, 0%, 50%)')
HSLA_COLOUR = Color.from_string('hsla(100, 0%, 50%, 0.5)')
还可以指定基本颜色
BLACK = Color.from_string('black')
CHOCOLATE = Color.from_string('chocolate')
HOTPINK = Color.from_string('hotpink')
如果元素未设置颜色,则有时浏览器将返回“透明”的颜色值。Color类也支持以下内容。
TRANSPARENT = Color.from_string('transparent')
现在可以安全地查询元素以获取其颜色或背景色,直到任何响应都会被正确解析并转换为有效的Color对象。
login_button_colour = Color.from_string(driver.find_element(By.ID,'login').value_of_css_property('color'))login_button_background_colour = Color.from_string(driver.find_element(By.ID,'login').value_of_css_property('background-color'))
还可以直接比较颜色对象。
assert login_button_background_colour == HOTPINK
可以将颜色转换为以下格式之一,并执行静态验证。
assert login_button_background_colour.hex == '#ff69b4'
assert login_button_background_colour.rgba == 'rgba(255, 105, 180, 1)'
assert login_button_background_colour.rgb == 'rgb(255, 105, 180)'
JavaScript的应用
JavaScript是Web页面的编程语言。Selenium提供了execute_script方法,用来执行JavaScript,从而完成一些特殊的操作。
高亮显示正在被操作的页面元素
测试过程中,我们可以借助JavaScript高亮显示正在被操作的元素。
from selenium.webdriver.common.by import Bydef highLightElement(driver, element):'''#封装高亮显示页面元素的方法:使用js代码将页面元素对象的背景颜色设置为绿色,边框设置为红色:param driver::param element::return:'''driver.execute_script("arguments[0].setAttribute('style', arguments[1]);", element,"background: green; border: 2px solid red;")if __name__ == '__main__':from selenium import webdriverfrom time import sleepdriver = webdriver.Chrome()driver.get('https://www.baidu.com/')ele = driver.find_element(By.ID,'kw')highLightElement(driver, ele)sleep(3)driver.quit()
修改页面元素属性
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>日期时间控件</title>
</head>
<body>
<input type="date" name="name1" id="id1" readonly>
</body>
</html>
from selenium import webdriver
from time import sleep
import osfrom selenium.webdriver.common.by import Bydriver = webdriver.Chrome()
html_file = 'File:///' + os.getcwd() + os.sep + 'myhtml.html'
driver.get(html_file)
sleep(2)
driver.find_element(By.TAG_NAME,'input').send_keys('002020/06/06')
sleep(5)
driver.quit()
执行脚本,虽然没有报错,但是内容并没写入文本框。接下来我们通过JavaScript先删除掉readonly属性,再来输入内容。
from selenium import webdriver
from time import sleep
import osfrom selenium.webdriver.common.by import Bydriver = webdriver.Chrome()
html_file = 'File:///' + os.getcwd() + os.sep + 'myhtml.html'
driver.get(html_file)
sleep(2)
js2 = "document.getElementById('id1').removeAttribute('readonly')"
driver.execute_script(js2)driver.find_element(By.TAG_NAME,'input').send_keys('002020/06/06')
sleep(5)
driver.quit()
操作页面元素
from selenium import webdriver
from time import sleepdriver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
ele1JS = "document.getElementById('kw').value='storm'"
ele2JS = "document.getElementById('su').click()"
driver.execute_script(ele1JS)
sleep(3)
driver.execute_script(ele2JS)
sleep(3)
driver.quit()
运行成功,通过removeAttribute方法成功删除掉了readonly属性并输入了内容。另外,再提供以下几种删除元素属性的方法
# js = "document.getElementById('c-date1').removeAttribute('readonly')" # 原生js,移除属性
# js = "$('input[id=c-date1]').removeAttr('readonly')" # jQuery,移除属性
# js = "$('input[id=c-date1]').attr('readonly',False)" # jQuery,设置为False
# js = "$('input[id=c-date1]').attr('readonly','')" # jQuery,设置为空
ele = driver.find_element_by_id('reg_butt')
js1 = "arguments[0].click()"
driver.execute_script(js1,ele)
操作滚动条
借助JavaScript操作纵向滚动条
from selenium import webdriver
from time import sleepfrom selenium.webdriver.common.by import Bydriver = webdriver.Chrome()
# driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
driver.find_element(By.ID,'kw').send_keys("storm")
driver.find_element(By.ID,'su').click()
js1 = "window.scrollTo(0, document.body.scrollHeight)"# 滑动滚动条到底部
js2 = "window.scrollTo(0,0)"# 滑动到顶端
js3 = "window.scrollTo(0,200)"# 向下滑动200像素
js4 = "arguments[0].scrollIntoView();" # 滑动到指定元素
sleep(2) #等待页面加载完,注意观察滚动条目前处于最上方
driver.execute_script(js1) #执行js1,将滚动条滑到最下方
sleep(2) #加等待时间,看效果
driver.execute_script(js2) #执行js2,将滚动条滑到最上方
sleep(2) #加等待时间,看效果
driver.execute_script(js3) #执行js3,将滚动条向下滑动到200像素
sleep(2) #加等待时间,看效果
driver.execute_script(js2) #执行js2,将滚动条滑到最上方
sleep(2)
ele = driver.find_element(By.ID,'con-ar') #定位一个元素
driver.execute_script(js4,ele) #滑动到上面定位的元素的地方
sleep(2)
driver.quit()
借助JavaScript操作横向滚动条
from selenium import webdriver
from time import sleepdriver = webdriver.Chrome()
# driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
driver.find_element('id','kw').send_keys("storm")
driver.find_element('id','su').click()
driver.set_window_size(500,500) #缩小浏览器窗口,使之出现横向滚动条
js5 = "window.scrollTo(document.body.scrollWidth,0)"
js6 = "window.scrollTo(0,0)"
js7 = "window.scrollTo(200,0)"
driver.execute_script(js5) #滑动到最右边
sleep(2)
driver.execute_script(js6) #滑动到最左边
sleep(2)
driver.execute_script(js7) #向右滑动200像素
sleep(2)
driver.quit()
操作内嵌滚动条
内嵌滚动条一般嵌在一个iframe里面,先切换到要操作的滚动条所在的iframe,然后正常调用JavaScript即可。
from selenium import webdriver
from time import sleepdriver = webdriver.Chrome()
# driver = webdriver.Firefox()
driver.get("http://sahitest.com/demo/iframesTest.htm")
sleep(2)
driver.switch_to.frame(1)
js5 = "window.scrollTo(0,200)"
driver.execute_script(js5) #向下滑动200像素
sleep(2)
driver.quit()
引申通过ActionChains 实现滚动条
import time
from time import sleepfrom selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin'''
scroll_to_element: 滚动条移动到元素
'''
def test_can_scroll_to_element(driver):driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")time.sleep(1)iframe = driver.find_element(By.TAG_NAME, "iframe")ActionChains(driver)\.scroll_to_element(iframe)\.perform()time.sleep(5)assert _in_viewport(driver, iframe)def test_can_scroll_from_viewport_by_amount(driver):driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")footer = driver.find_element(By.TAG_NAME, "footer")delta_y = footer.rect['y']print(delta_y)ActionChains(driver)\.scroll_by_amount(0, delta_y)\.perform()sleep(0.5)assert _in_viewport(driver, footer)def test_can_scroll_from_element_by_amount(driver):driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")iframe = driver.find_element(By.TAG_NAME, "iframe")scroll_origin = ScrollOrigin.from_element(iframe)ActionChains(driver)\.scroll_from_origin(scroll_origin, 0, 200)\.perform()sleep(0.5)driver.switch_to.frame(iframe)checkbox = driver.find_element(By.NAME, "scroll_checkbox")sleep(3)assert _in_viewport(driver, checkbox)def test_can_scroll_from_element_with_offset_by_amount(driver):driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")footer = driver.find_element(By.TAG_NAME, "footer")scroll_origin = ScrollOrigin.from_element(footer, 0, -50)ActionChains(driver)\.scroll_from_origin(scroll_origin, 0, 200)\.perform()sleep(2)iframe = driver.find_element(By.TAG_NAME, "iframe")driver.switch_to.frame(iframe)checkbox = driver.find_element(By.NAME, "scroll_checkbox")assert _in_viewport(driver, checkbox)def test_can_scroll_from_viewport_with_offset_by_amount(driver):driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")sleep(2)scroll_origin = ScrollOrigin.from_viewport(10, 10)ActionChains(driver)\.scroll_from_origin(scroll_origin, 0, 200)\.perform()sleep(3)iframe = driver.find_element(By.TAG_NAME, "iframe")driver.switch_to.frame(iframe)checkbox = driver.find_element(By.NAME, "scroll_checkbox")assert _in_viewport(driver, checkbox)def _in_viewport(driver, element):script = ("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n""e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n""return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n""window.pageYOffset&&t+o>window.pageXOffset")return driver.execute_script(script, element)
操作span类型元素
实际项目中可能会遇到span类型元素,针对此类型元素,有一些特殊的操作
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>span类型元素测试</title>
</head>
<body><span id="span_id">span的文本</span>
</body>
</html>
通过id来定位元素,获取span的文本
from selenium import webdriver
import os'''
定位元素,通过text取文本
'''
driver = webdriver.Chrome()
html_file = 'File:///' + os.getcwd() + os.sep + 'myhtml.html'
driver.get(html_file)
ele = driver.find_element('id','span_id')
print(ele.text)
driver.quit()
通过JavaScript修改标签的文本
from selenium import webdriver
from time import sleep
import os'''
通过js的方式修改span中间的值
js = 'document.getElementById("span_id").innerText="aaaa"'
'''
driver = webdriver.Chrome()
html_file = 'File:///' + os.getcwd() + os.sep + 'myhtml.html'
driver.get(html_file)
sleep(2)
js1 = "document.getElementById('span_id').innerText='aaa'"
driver.execute_script(js1)
sleep(2)
driver.quit()
相关文章:

selenium高级应用
常见控件应用 复杂的控件操作1.操作Ajax选项2.滑动滑块操作 WebDriver的特殊操作元素class值包含空格property、attribute、text的区别定位动态id 截图功能页面截图页面截图,返回截图的二进制数据页面截图,返回base64的字符串截取指定元素。先定位元素&a…...
微信小程序重新加载当前页面、刷新当前页面
重新加载页面 使用wx.reLanuch(),url: 路径当前页面跳转, 页面所有数据重新初始化,已配置的数据不会保存 wx.reLaunch({url: /pages/orders/createOrder/createOrder, // 当前页面的路径}) reLanuch()的方法,会有一个…...

如何查找、恢复误清空的 Android 回收站?
“我的回收站里有一些照片。当我点击“恢复”时,没有任何反应。我可以将我的 Android 手机插入我的电脑。这样我就可以手动恢复它们。但我在 Android 上找不到 bin 文件夹。我还可以做些什么?” 随着 Android 手机上的文件数量不断增加,了解…...

Node.js作用
Node.js可以开发应用 开发服务器应用 开发工具类应用 开发桌面端应用...
Web爬虫入门:原理、实现与常见问题解决指南
引言: 在当今数据驱动的时代,网络上蕴藏着无尽的信息宝藏,而爬虫技术则是探索和利用这些宝藏的重要工具。爬虫,简单来说,就是一种自动化程序,它能够模拟人类浏览网页的行为,从中提取所需数据。…...

蓝桥杯练习题——归并排序
1.火柴排队 思路 1.求最小值的时候,可以直接按升序排序,这样得到的值就是最小值 2.求最小交换次数的时候,不能直接排序,因为只能交换相邻的数,只需要知道他们的相对大小,所以可以先用离散化,把…...

C语言--- 指针运算笔试题详解
目录 题目1: 题目2: 题目3: 题目4: 题目5: 题目6: 题目7: 题目1: #include <stdio.h> int main() {int a[5] { 1, 2, 3, 4, 5 };int *ptr (int *)(&a 1);print…...

甘特图是什么,怎么制作?一文让你看懂
甘特图是什么 甘特图是一种项目管理工具,通过图形化的方式直观的能体现出任务、进度和资源在时间里的关系。 白话文就是: 项目分解成了哪些任务?每天计划做什么任务?当前每个任务的进度是多少?项目整体进度是多少?这个项目有…...
mysql笔记:6. 存储引擎
文章目录 查看引擎信息常用引擎介绍InnoDBMyISAMMEMORY存储引擎的选择 数据库存储引擎是数据库底层组件,数据库管理系统使用数据引擎进行创建、查询、更新和删除数据。不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等,使用不同的存储引擎&#…...

(golang)切片何时会创建新切片或影响原切片
什么时候切片操作会影响原切片 // 1.切片后没有触发slice的扩容机制时 什么时候对切片操作会创建新切片不影响原切片 // 2.对切片头元素进行截取的时候 // 3.当使用append时,len > cap则会触发扩容机制 前置: //slice结构体 type SliceHeader struct…...
前端面试——W3C标准及规范
W3C标准 1、万维网联盟标准不是某一个标准,而是一些列标准的集合。 简单来说可以分为结构、表现和行为 结构 主要是有HTML标签组成 表现 即指css样式表 行为 主要是有js、dom组成 web标准一般是将该三部分独立分开,使其更具有模块化。但一般产生行为时&…...

读算法的陷阱:超级平台、算法垄断与场景欺骗笔记07_价格歧视
1. 行为歧视 1.1. 单个企业通过使用数据驱动的算法,从而更好地实现锁定客户、开展个性化营销与定价的目的 1.2. 市场环境再次发生了变化 1.2.1. 在共谋场景中,定价算法提高了企业经营者在销量数据上的透明性…...

数据结构 之 链表LinkedList
目录 1. ArrayList的缺陷: 2. 链表: 2.1 链表的概念及结构: 3. 链表的使用和模拟实现: 3.1 构造方法: 3.2 模拟实现: 4. 源码分享: 在我学习顺序表之后,我就立马开始了链表的学…...

事务【MySQL】
事务的概念 引入 在 A 转账 100 元给 B 的过程中,如果在 A 的账户已经减去了 100 元,B 的账户还未加上 100 元之前断网,那么这 100 元将会凭空消失。对于转账这件事,转出和转入这两件事应该是绑定在一起的,任意一个动…...

Anaconda 的一些配置
Anaconda 安装及修改环境默认位置 https://blog.csdn.net/qq_54562136/article/details/128932352 最重要的一步!!!!!改文件夹权限 Anaconda创建、激活、退出、删除虚拟环境 修改pip install 默认安装路径...

利用Nginx正向代理实现局域网电脑访问外网
引言 在网络环境中,有时候我们需要让局域网内的电脑访问外网,但是由于网络策略或其他原因,直接访问外网是不可行的。这时候,可以借助 Nginx 来搭建一个正向代理服务器,实现局域网内电脑通过 Nginx 转发访问外网的需求…...

SpringMVC03、HelloSpring
3、HelloSpring 3.1、配置版 新建一个Moudle , springmvc-02-hello , 添加web的支持! 确定导入了SpringMVC 的依赖! 配置web.xml , 注册DispatcherServlet <?xml version"1.0" encoding"UTF-8…...
IOS面试题object-c 1-10
1、简述Object-C的理解与特性? OC 作为一门 面向对象 的语言,自然具有面向对象的语言特性:封装、继承、多态。 它既具有 静态语言的特性(如C),又有 动态语言的效率(动态绑定、动态加载等&#…...

原生JavaScript,根据后端返回扁平JSON动态【动态列头、动态数据】生成表格数据
前期准备: JQ下载地址: https://jquery.com/ <!DOCTYPE html> <html><head><meta charset"utf-8"><title>JSON动态生成表格数据,动态列头拼接</title><style>table {width: 800px;text-align: cen…...

hadoop报错:HADOOP_HOME and hadoop.home.dir are unset. 解决方法
参考:https://blog.csdn.net/weixin_45735242/article/details/120579387 解决方法 1.下载apache-hadoop-3.1.0-winutils-master 官网下载地址: https://github.com/s911415/apache-hadoop-3.1.0-winutils win配置系统环境: 然后重启idea…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...