基于Python的Selenium详细教程
一、PyCharm安装配置Selenium
本文使用环境:windows11、Python 3.10.5、PyCharm 2022.1.3、Selenium 4.3.0
需要你懂的技术:Python、HTML、CSS、JavaScript
1.Seleium安装:
在PyCharm终端或window命令窗口输入以下命令
#查看已安装的Python包(可跳过)pip list#安装selenium 4.3.0pip install selenium==4.3.0
注意:在window命令窗口安装时,首先要确保Python环境变量配置正确
##卸载Selenium命令pip uninstall selenium
2.配置浏览器驱动
- 下载浏览器驱动
这里给出各浏览器(Chrome、Firefox、Edge等)的驱动下载地址,自行下载所需浏览器驱动。 - 将下载好的浏览器驱动放置在Python安装目录下(即Python环境变量配置目录)
3. 验证
在PyCharm中新建一个Python文件,自行命名,输入以下代码:
import time
# 导入selenium包
from selenium import webdriver
# 打开Firefox浏览器
browser = webdriver.Firefox()
# 停留三秒
time.sleep(3)
# 关闭浏览器
browser.quit()
执行后,Firefox浏览器将被打开,证明Selenium安装配置完成
- 启动Chrome浏览器
# 打开Chome浏览器
browser = webdriver.Chrome()
# 关闭浏览器
browser.quit()
- 启动Edge浏览器
# 打开Edge浏览器
browser = webdriver.Edge()
# 关闭浏览器
browser.quit()
二、Selenium使用
2.1、加载指定页面并关闭
import time
# 导入selenium包
from selenium import webdriver
# 打开指定(Firefox)浏览器
browser = webdriver.Firefox()
# 指定加载页面
browser.get("http://www.csdn.net/")
# 设置五秒后执行下一步
time.sleep(5)
# 关闭浏览器
browser.quit()
2.2 、元素定位
元素定位方法包含了2个系列:
- find_element()系列:用于定位单个的页面元素。
- find_elements()系列:用于定位一组页面元素,获取到的是一组列表。
1、通过标签id属性定位
- find_element(By.ID,‘XX’)id定位,根据元素的id属性值定位,最为方便且唯一,但有可能不存在,也可能动态生成。
import time
# 导入selenium包
from selenium import webdriver
from selenium.webdriver.common.by import By
# 打开指定(Firefox)浏览器
browser = webdriver.Firefox()
# 指定加载页面
browser.get("http://www.csdn.net")
# 通过id属性获取搜索输入框
input_text = browser.find_element(By.ID, "toolbar-search-input")
# 向搜索输入框内输入selenium
input_text.send_keys("selenium")
# 设置停留五秒后执行下一步
time.sleep(5)
# 关闭浏览器
browser.quit()
2、通过标签name属性定位
find_element(By.NAME,‘xx’)name定位,根据元素的name属性值定位,定位到的标签不一定是唯一的。
import time
# 导入selenium包
from selenium import webdriver
from selenium.webdriver.common.by import By
# 启动并打开指定页面
browser = webdriver.Firefox()
browser.get("http://www.baidu.com/")
# 通过name属性选择文本框元素,并设置内容
browser.find_element(By.NAME,'wd').send_keys("selenium")
# 通过通过ID属性获取“百度一下”按钮,并执行点击操作
browser.find_element(By.ID,"su").click()
# 停留五秒后关闭浏览器
time.sleep(5)
browser.quit()
3、通过标签class属性定位
- find_element_by(By.CLASS_NAME,‘xx’)class定位,根据元素的class属性值定位,但可能受JS影响动态变化。定位到的标签不一定是唯一的。
import time
# 导入selenium包
from selenium import webdriver
from selenium.webdriver.common.by import By
# 启动并打开指定页面
browser = webdriver.Firefox()
browser.get("http://www.baidu.com/")
time.sleep(2)
# 通过class属性选择元素
browser.find_element(By.CLASS_NAME,'s_ipt').send_keys("CSDN")
time.sleep(2)
browser.find_element(By.ID,"su").click()
# 停留三秒后关闭浏览器
time.sleep(3)
browser.quit()
4、通过标签tag定位
- find_element(By.TAG_NAME,‘xx’)tag name定位,根据元素的标签名定位,定位到的标签不一定是唯一的。
import time
# 导入selenium包
from selenium import webdriver
from selenium.webdriver.common.by import By
# 启动并打开指定页面
browser = webdriver.Firefox()
browser.get("http://www.csdn.net")
time.sleep(2)
# 选择<button></button>标签(搜索按钮),执行点击操作
browser.find_element(By.TAG_NAME, "button").click()
# 停留三秒后关闭浏览器
time.sleep(3)
browser.quit()
5、通过link定位
- link表示包含有属性href的标签元素,如:linktext可以通过LINK_TEXT进行定位。
- find_element(By.LINK_TEXT,‘XX’)根据链接文本全匹配进行精确定位。
- find_element(By.PARTIAL_LINK_TEXT,‘XX’)根据链接文本模糊匹配进行定位。
(1)、By.LINK_TEXT精确定位
import time
# 导入selenium包
from selenium import webdriver
from selenium.webdriver.common.by import By
# 启动并打开指定页面
browser = webdriver.Firefox()
browser.get("http://www.csdn.net")
# 选择<a href="https://blog.csdn.net/nav/back-end">Python</a>标签,执行点击操作
browser.find_element(By.LINK_TEXT, "Python").click()
# 停留三秒后关闭浏览器
time.sleep(3)
browser.quit()
(2)By.PARTIAL_LINK_TEXT模糊定位
import time
# 导入selenium包
from selenium import webdriver
from selenium.webdriver.common.by import By
# 启动并打开指定页面
browser = webdriver.Firefox()
browser.get("http://www.csdn.net")
# 选择<a href="href="https://blog.csdn.net/nav/ai">人工智能</a>标签,执行点击操作
browser.find_element(By.PARTIAL_LINK_TEXT, "人工").click()
# 停留五秒后关闭浏览器
time.sleep(3)
browser.quit()
6、通过元素的xpath定位
xpath是一种在XML文档中定位元素的语言
-
使用绝对路径定位
指的是从网页的HTML代码结构的最外层一层层的写到需要被定位的页面元素为止。
绝对路径起始于/,每一层都被/所分割。
/html/body/div[2]/form/input[3]
注解:
(1)可以用中括号选择分支,div[2]代表的是当前层级下的第二个div标签;
(2)一般情况下较少使用绝对路径的方式做定位,原因在于绝对路径的表达式一般太长,不便于后期的代码维护,代码的微小改变就可能导致这个路径失效,从而无法完成元素定位。 -
使用相对路径定位
不是从根目录写起,而是从网页文本的任意目录开始写。
相对路径起始于//,//所表示的含义是“任意标签下”
//input[@id=‘kw’]
注解:
(1)示例的含义:在当前页面查找任意目录下的input元素,且该元素的id属性取值为kw
(2)在xpath里,属性以@开头
(3)所选取的属性可以是任意属性,只要其有利于标识这个元素即可
(4)推荐使用相对路径结合属性的这种xpath表达式,它往往更简洁更易于维护
(5)有时候可能会出现一个属性不足以标识某个元素,可以使用逻辑运算符and来连接多个属性进行标识。//input[@xx=‘aa’ and @yy=‘bb’]
(6)有时候一个元素它本身没有可以唯一标识它的属性,这时我们可以找它的上层或者上上层, 然后再往下写。//input[@xx=‘aa’]/p -
find_element(By.XPATH,‘XX’)根据元素的xpath表达式来完成定位,可以准确定位任何元素。
打开CSDN首页,按F12进入开发者模式,我们可以按照下图所示获取元素的xpath路径,我这里定位的是搜索框的xpath。
点击后会存在与剪切板中,Ctrl+v粘贴到代码中即可使用,这里获取到的是相对路径。
import time
# 导入selenium包
from selenium import webdriver
from selenium.webdriver.common.by import By# 启动并打开指定页面
browser = webdriver.Firefox()
browser.get("http://www.csdn.net")
# 通过xpath定位输入框,输入内容selenium
browser.find_element(By.XPATH, '//*[@id="toolbar-search-input"]').send_keys('selenium')
# 停留五秒后关闭浏览器
time.sleep(5)
browser.quit()
7、通过css选择器定位
- find_element(By.CSS_SELECTOR,‘XX’)根据元素的css选择器来完成定位,可以准确定位任何元素,但需要熟练掌握css选择器
- css选择器
(1)类选择器--------.XXX选择class属性为xxx的元素
(2)id选择器-------- #XXX选择id属性为xxx的元素
(3)元素选择器-----XXX选择标签名为xxx的元素
(4)属性选择器-----[yyy=‘bbb’]选择yyy属性取值为bbb的元素
(5)派生选择器-----AA>XX或AA XX选择AA标签下的XX元素
你可以通过获取xpath的方式来从页面获取css选择器 - 在css里标识层级关系使用的是>或者空格(xpath里使用的是/)
div#xx1>input.yy2
注意:对于css的属性值来说,可以加引号也可以不加,注意属性的引号和整个CSS表达式的引号要进行区分。对于xpath的属性值来讲,需要加上引号,否则报错。
import time
# 导入selenium包
from selenium import webdriver
from selenium.webdriver.common.by import By
# 启动并打开指定页面
browser = webdriver.Firefox()
browser.get("http://www.csdn.net")
# 通过css选择器定位输入框,输入内容selenium
browser.find_element(By.CSS_SELECTOR, '#toolbar-search-input').send_keys('selenium')
# 停留三秒后关闭浏览器
time.sleep(3)
browser.quit()
8、几种元素定位方式区别
2.3、文本输入、清除与提交
- send_keys(‘XXX’)文本输入。
- clear()文本清空。
import time
# 导入selenium包
from selenium import webdriver
from selenium.webdriver.common.by import By
# 启动并打开指定页面
browser = webdriver.Firefox()
browser.get("http://www.csdn.net")
# 通过css选择器定位输入框
input_text = browser.find_element(By.CSS_SELECTOR,'#toolbar-search-input')
# 输入文本
input_text.send_keys("selenium")
# 停留2秒
time.sleep(2)
# 清空文本
input_text.clear()
# 停留三秒后关闭浏览器
time.sleep(3)
browser.quit()
- submit()提交
- 注意:submit()只能用于包含属性type='submit’的标签,并且嵌套在form表单中。
- 也可以使用click()代替submit()使用。
- 注意:submit()和click()是有很大区别的,这里不再做具体说明。
import time
# 导入selenium包
from selenium import webdriver
from selenium.webdriver.common.by import By
# 启动并打开指定页面
browser = webdriver.Firefox()
browser.get("http://www.bing.com")
# 通过xpath选择器定位输入框,并输入CSDN
input_text = browser.find_element(By.XPATH,'//*[@id="sb_form_q"]').send_keys("CSDN")
time.sleep(2)
# 定位提交按钮后提交
browser.find_element(By.XPATH,'//*[@id="sb_form_go"]').submit()
# 停留3秒后关闭
time.sleep(3)
browser.quit()
2.4、获取页面内容
- title页面标题
- page_source 页面源码
- current_url页面连接
- text标签内文本
import time
# 导入selenium包
from selenium import webdriver
from selenium.webdriver.common.by import By
# 启动并打开指定页面
browser = webdriver.Firefox()
browser.get("http://www.csdn.net")
# 获取标题
title = browser.title
# 输出
print(title)
# 获取源代码
source_code = browser.page_source
#输出源代码
print(source_code)
# 获取页面链接
url = browser.current_url
#输出页面链接
print(url)
# 获取标签内文本
text = browser.find_element(By.XPATH, '/html/body/div[1]/div/div/div/div[2]/div/div/button/span').text
print(text)
# 关闭页面
time.sleep(3)
browser.quit()
输出结果太多,这里不在展示,自行在PyCharm上演示。
2.5、隐式等待
implicitly_wait(N)通过一定时长等待页面元素加载,最大等待时长N秒,如果中间某个时刻元素加载好了,就会结束等待,执行下一步操作;如果超出设置时间元素没加载出来,抛出没有这样的元素异常。
import time
# 导入selenium包
from selenium import webdriver
from selenium.webdriver.common.by import By
# 启动并打开指定页面
browser = webdriver.Firefox()
browser.get("http://www.csdn.net")
# 隐式等待
browser.implicitly_wait(5)
# 关闭页面
browser.quit()
time.sleep(3)
2.6、调整浏览器窗口尺寸
- maximize_window()窗口最大化。
- minimize_window()窗口最小化。
- set_window_size(width,height)调整窗口到指定尺寸。
import time
# 导入selenium包
from selenium import webdriver
from selenium.webdriver.common.by import By
# 启动并打开指定页面
browser = webdriver.Firefox()
browser.get("http://www.csdn.net")
# 窗口最大化
browser.maximize_window()
#停留2秒
time.sleep(2)
#窗口最小化
browser.minimize_window()
# 指定窗口尺寸
browser.set_window_size(300, 500)
# 关闭页面
time.sleep(3)
browser.quit()
2.7、前进一页后退一页
forward()前进一页。
back()后退一页。
import time
# 导入selenium包
from selenium import webdriver
from selenium.webdriver.common.by import By# 启动并打开指定页面
browser = webdriver.Firefox()
browser.get("http://www.csdn.net")
browser.find_element(By.LINK_TEXT, 'Python').click()
#停留2秒
time.sleep(2)
# 页面后退一页
browser.back()
# 停留2秒
time.sleep(2)
# 前进一页
browser.forward()
# 关闭页面
time.sleep(3)
browser.quit()
2.8、页面刷新
- refresh()页面刷新
import time
# 导入selenium包
from selenium import webdriver
from selenium.webdriver.common.by import By
# 启动并打开指定页面
browser = webdriver.Firefox()
browser.get("http://www.csdn.net")
browser.find_element(By.LINK_TEXT, 'Python').click()
#停留2秒
time.sleep(2)
# 页面刷新
browser.refresh()
# 关闭页面
time.sleep(3)
browser.quit()
2.9、窗口切换
- current_window_handle获取当前窗口的句柄
- window_handles获取所有打开页面的句柄,是一个列表
- switch_to.window(“XX”)切换到指定页面,XX代表页面句柄
- switch_to.frame(XX)切换到内敛框架页面,XX代表内联框架标签的定位对象,演示请看章节2.10源码。
- swith_to.parent_frame()切回到内敛框架的上一级,即从内敛框架切出。演示请看章节2.10源码。
- switch_to.alert切换到页面弹窗,演示请看章节2.13源码。
from time import sleep
# 导入selenium包
from selenium import webdriver
from selenium.webdriver.common.by import By
# 启动并打开指定页面
browser = webdriver.Firefox()
browser.get("http://www.csdn.net")
sleep(2)
# 获取当前窗口句柄
page_context = browser.current_window_handle
# 打开其它页面
browser.find_element(By.XPATH, '//*[@id="toolbar-search-input"]').send_keys('selenium')
browser.find_element(By.XPATH, '/html/body/div[1]/div/div/div/div[2]/div/div/button/span').click()
sleep(2)
# 切换到刚开始打开页面
browser.switch_to.window(page_context)
# 获取当前打开所有页面的句柄
pages_context = browser.window_handles
# 输出当前打开页面个数
print(len(pages_context)) # 结果:2
# 关闭
sleep(3)
browser.quit()
2.10、frame/iframe内元素操作
选取框架内元素,首先我们要定位到框架元素,然后切换到框架页面,才能对框架页面内元素进行操作。
由于找不到内敛框架的页面,这里我自己简单写了个页面。下边是HTML源码,操作时注意路径get()内url不要写错。
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>frame内敛框架页面</title>
</head>
<body>这是框架frame外:<input type="text" ><iframe id='frame' src="http://www.csdn.net" width=1000px height=500px></iframe>
</body>
</html>
- switch_to.frame(tag_iframe)切换到frame/iframe框架页面。
- switch_to.parent_frame()从内敛框架中切出。
from time import sleep
# 导入selenium包
from selenium import webdriver
from selenium.webdriver.common.by import By
# 启动并打开指定页面
browser = webdriver.Firefox()
browser.get("file:///C:/Users/admin/Desktop/frame.html")
sleep(2)
# 定位到iframe标签
tag_iframe = browser.find_element(By.TAG_NAME, 'iframe')
# 切换到iframe框架页面内
browser.switch_to.frame(tag_iframe)
# 定位到框架内搜索框并输入内容
browser.find_element(By.LINK_TEXT, 'Python').click()
sleep(2)
# 从内敛框架页面切出
browser.switch_to.parent_frame()
browser.find_element(By.XPATH, "//input").send_keys("这是框架外面!")
# 关闭浏览器
sleep(3)
browser.quit()
2.11、获取标签元素的属性值(复选框)
- get_attribute(“XX”)获取标签属性值,XX为标签属性名。
- 这里我们通过获取标签元素的属性值,对标签进行操作。以下示例为通过获取复选- 框标签的属性值对复选框进行选取。
- 页面HTML源码:
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title></title>
</head>
<body>用户名:<input type="text" name="user_name">密码:<input type="password" name="pwd"><input type="checkbox" name="Java">Java<input type="checkbox" name="Python">Python<input type="checkbox" name="C++">C++<input type="checkbox" name="JavaScript">JavaScript<input type="checkbox" name="HTML">HTML
</body>
</html>
- Python源码
import time
# 导入selenium包
from selenium import webdriver
from selenium.webdriver.common.by import By
# 启动并打开指定页面
browser = webdriver.Firefox()
browser.get("file:///C:/Users/admin/Desktop/checkbox.html")
# 定位input标签
tag_input = browser.find_elements(By.TAG_NAME, 'input')
# 通过type属性的值来定位元素,并进行选取
for type_value in tag_input:# 输出input标签的name属性的值:print(type_value.get_attribute("name"))# 对复选框进行选取操作if type_value.get_attribute("type") == "checkbox":type_value.click()time.sleep(2)
# 关闭浏览器
time.sleep(3)
browser.quit()
- 控制台输出结果:
user_name
pwd
Java
Python
C++
JavaScript
HTML
2.12、下拉列表操作
- Select("XX)判断标签元素XX是否为下拉列表元素,是返回Select对象,不是报错
- select_by_value(“XX”)通过下拉列表value属性的值XX选择选项
- select_by_visible_text(“XX”)通过下拉列表文本内容XX选择选项
- select_by_index(N)或options[N].click()通过下拉列表索引号N选则选项,从0 开始
- options下拉列表内options标签
- 页面HTML源码:
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title></title>
</head>
<body>编程语言:<select><option>Java</option><option>C++</option><option value="Python">Python</option><option>HTML</option><option>JavaScript</option></select>
</body>
</html>
- Python 源码
from time import sleep
# 导入selenium包
from selenium import webdriver
from selenium.webdriver.common.by import By
# 导入Select类
from selenium.webdriver.support.select import Select# 启动并打开指定页面
browser = webdriver.Firefox()
browser.get("file:///C:/Users/admin/Desktop/select.html")
# 定位下拉列表标签,并创建下拉列表对象
select = Select(browser.find_element(By.TAG_NAME, "select"))
# 通过value属性选择选项
select.select_by_value("Python")
sleep(2)
# 通过文本内容选择选项
select.select_by_visible_text("C++")
sleep(2)
# 通过选项索引号选择选项
select.select_by_index(0) # 等同于 select.options[0].click()
sleep(2)
# 通过options属性循环选取
for i in select.options:i.click()sleep(2)
# 关闭浏览器
sleep(3)
browser.quit()
2.13、弹窗操作
- switch_to.alert获取弹窗对象。
- text弹窗内容
- accept()接受弹窗
- dismiss()取消弹窗
页面HTML源码
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title></title>
</head>
<body><input type="button" id="alert" value="alert弹窗" onclick="alert('这是alert()弹窗!')"><input type="button" id="confirm"value="confirm弹窗" onclick="confirm('这是confirm()弹窗!')" ><input type="button" id="prompt" value="prompt弹窗" onclick="prompt('这是prompt()弹窗!','这是prompt()弹窗的默认值!')">
</body>
</html>
Python源码
from time import sleep
# 导入selenium包
from selenium import webdriver
from selenium.webdriver.common.by import By
# 启动并打开指定页面
browser = webdriver.Firefox()
browser.get("file:///C:/Users/admin/Desktop/alert.html")
# alert()弹窗处理
browser.find_element(By.ID, "alert").click()
sleep(2)
# 获取弹窗对象
alert = browser.switch_to.alert
# 输出弹窗内容
print(alert.text) # 结果:这是alert()弹窗!
# 确认弹窗
alert.accept()
sleep(2)
# confirm()弹窗
browser.find_element(By.ID, "confirm").click()
sleep(2)
# 获取弹窗对象
confirm = browser.switch_to.alert
# 输出弹窗内容
print(confirm.text) # 这是confirm()弹窗!
# 执行性弹窗的取消按钮
confirm.dismiss() # confirm.accept() # 执行弹窗确认按钮
sleep(2)
# prompt()弹窗
browser.find_element(By.ID, "prompt").click()
sleep(2)
# 获取弹窗对象
prompt = browser.switch_to.alert
# 输出弹窗内容
print(prompt.text) # 这是prompt()弹窗!
# 向弹窗的输入框内输入内容
prompt.send_keys("这是弹窗prompt()")
sleep(2)
# 执行性弹窗的确认按钮
prompt.accept()
# 关闭浏览器
sleep(3)
browser.quit()
2.14、鼠标操作
-
鼠标操作涉及到的类:ActionChains类
-
move_to_element(X)鼠标悬停,X代表定位到的标签
-
double_click(X)双击
-
context_click(X)右击
-
perform() 执行所有存储在ActionChains()类中的行为,做最终的提交
不管执行哪个方法,最后都要调用perform()方法,将操作呈现出来。
from time import sleep
# 导入selenium包
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
# 启动并打开指定页面
browser = webdriver.Firefox()
browser.get("https://www.csdn.net")
sleep(2)
# 创建ActionChains对象
action = ActionChains(browser)
# 定位标签并将鼠标移入,并呈现移入结果
tag = browser.find_element(By.XPATH, '//div/a[@class="btn-write-new"]')
action.move_to_element(tag).perform()
sleep(3)
tag = browser.find_element(By.CSS_SELECTOR, '.blog-nav-box')
action.move_to_element(tag).perform()
sleep(2)
browser.find_element(By.LINK_TEXT, "数学").click()
# 关闭浏览器
sleep(2)
browser.quit()
2.15、键盘操作
- send_keys(Keys.BACK_SPACE)执行回退键Backspace
- send_keys(Keys.CONTROL,‘a’)全选
- send_keys(Keys.CONTROL,‘x’)剪切
- send_keys(Keys.CONTROL,‘c’)复制
- send_keys(Keys.CONTROL,‘v’)粘贴
from time import sleep
# 导入selenium包
from selenium import webdriver
from selenium.webdriver import ActionChains, Keys
from selenium.webdriver.common.by import By
# 启动并打开指定页面
browser = webdriver.Firefox()
browser.get("https://www.csdn.net")
sleep(2)
input_text = browser.find_element(By.XPATH, '//*[@id="toolbar-search-input"]')
input_text.send_keys("selenium")
sleep(2)
input_text.send_keys(Keys.CONTROL, "a") # 全选
sleep(2)
input_text.send_keys(Keys.CONTROL, 'x') # 剪切
sleep(2)
input_text.send_keys(Keys.CONTROL, 'v') # 粘贴
sleep(2)
input_text.send_keys(Keys.BACK_SPACE) # 回退一格
# 关闭浏览器
sleep(2)
browser.quit()
2.16、JS代码执行
- execute_script(X)执行JS代码,X代表要执行的JS代码
from time import sleep
# 导入selenium包
from selenium import webdriver
# 启动并打开指定页面
browser = webdriver.Firefox()
browser.get("https://www.csdn.net")
sleep(2)
# 执行js弹窗代码
browser.execute_script("alert('这是js弹窗代码')")
sleep(2)
browser.switch_to.alert.accept()
sleep(2)
# 执行js窗口滚动条代码
browser.execute_script("window.scrollTo(20,1000)")
sleep(2)
# 打开多个窗口
browser.execute_script("window.open('https://www.baidu.com')")
browser.execute_script("window.open('https://www.bing.com')")
sleep(2)
browser.quit()
2.17、窗口截图
- get_screenshot_as_file(XX)浏览器窗口截屏,XX代表文件保存地址及文件名、格式。只写文件名保存至当前路径,若写路径,则路径必须存在。
from time import sleep
# 导入selenium包
from selenium import webdriver
# 启动并打开指定页面
browser = webdriver.Firefox()
browser.get("https://www.csdn.net")
sleep(2)
# 浏览器窗口截屏
browser.get_screenshot_as_file("csdn.png")
sleep(2)
browser.quit()
2.18、三种等待方法
- sleep(n)强制等待,需要导入time包,n表示等待秒数;用于避免因元素未加载出来而定位失败的情况。
- implicitly_wait(n)隐式等待,如果超过n秒,抛出找不到元素的异常;隐式等待只需要声明一次,一般在打开浏览器后进行声明。隐式等待存在的问题是程序会一直等待整个页面加载完成才会执行下一步,有时候想要定位的元素早就加载好了,但是由于别的页面元素没加载好,仍会等到整个页面加载完成才能执行下一步。
- WebDriverWait(browser,n,h):显式等待,browser代表浏览器对象,n等待时长,h频率。相比于隐式等待,显式等待只针对指定的元素生效,不再是针对所有的页面元素。可以根据需要定位的元素来设置显式等待,无需等待页面完全加载,节省了大量因加载无关紧要的页面元素而浪费的时间。使用方法WebDriverWait(browser,5,0.5).until(expected_conditions.presence_of_element_located((By.ID,‘kw’)))
from selenium import webdriver
from time import sleep
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
browser = webdriver.Firefox()
sleep(2)
# 打开csdn首页
browser.get("https://www.csdn.net")
tag = WebDriverWait(browser, 5, 0.5).until(EC.presence_of_element_located((By.XPATH, '//*[@id="toolbar-search-input"]')))
tag.send_keys("selenium")
#关闭
sleep(2)
browser.quit()
最后给大家分享一下我的一些学习资料:
以上内容,对于软件测试的朋友来说应该是最全面最完整的备战仓库了,为了更好地整理每个模块,我也参考了很多网上的优质博文和项目,力求不漏掉每一个知识点,很多朋友靠着这些内容进行复习,拿到了BATJ等大厂的offer,这个仓库也已经帮助了很多的软件测试的学习者,希望也能帮助到你。
关注下方我的微信公众号免费领取!↓ ↓ ↓ ↓ ↓
相关文章:
基于Python的Selenium详细教程
一、PyCharm安装配置Selenium 本文使用环境:windows11、Python 3.10.5、PyCharm 2022.1.3、Selenium 4.3.0 需要你懂的技术:Python、HTML、CSS、JavaScript 1.Seleium安装: 在PyCharm终端或window命令窗口输入以下命令 #查看已安装的Pytho…...
金仓KDTS迁移工具报错ERROR: 对访问方法 “btree“ 数据类型 unknown 没有默认的操作符表
ERROR: 对访问方法 "btree" 数据类型 unknown 没有默认的操作符表 查看错误日志 com.kingbase8.util.KSQLException: ERROR: 对访问方法 "btree" 数据类型 unknown 没有默认的操作符表Hint: 你必须指定一个操作符表给索引或定义一个默认的操作符表给数据…...
前端开发入门指南Day 17:TypeScript高级类型(泛型,类型守卫,Partial<T>和 Required<T>等)
泛型:代码的"变色龙" 🦎 为什么需要泛型? 想象一个快递员,每天要处理不同类型的包裹。如果为每种类型的包裹都写一套处理程序,那会很麻烦。泛型就像是一个"通用的包裹处理系统",它能…...
数据链路层(四)---PPP协议的工作状态
1 PPP链路的初始化 通过前面几章的学习,我们学了了PPP协议帧的格式以及组成,那么对于使用PPP协议的链路是怎么初始化的呢? 当用户拨号上网接入到ISP后,就建立起了一条个人用户到ISP的物理链路。这时,用户向ISP发送一…...
EasyNVR中HTTP-FLV协议无法播放怎么解决?
在科技日新月异的今天,摄像头作为公共安全领域的重要一环,其技术的不断提升正显著地改变着社会的安全格局。从最初的简单监控到如今的高清智能分析,我们可以对特定区域进行实时监控和记录,为社会的安全稳定提供了强有力的保障。 问…...
微服务监控prometheus+Grafana
目录 Prometheus 概述 核心组件 特点 使用场景 Grafana 概述 功能特点 使用场景 PrometheusGrafana组合 部署和配置 一、准备工作 二、部署Prometheus 三、部署Grafana 四、创建监控仪表盘 五、验证和调优 总结 微服务监控是确保微服务架构稳定运行的关键环节…...
C++编程:模拟实现CyberRT的DataVisitor和DataDispatcher
文章目录 0. 引言1. 设计概要1.1 主要组件1.2 类关系图1.3 工作流程 2. 代码实现2.1. 定义数据结构2.2. 实现 DataVisitor2.3. 实现 DataDispatcher2.4. 实现 Receiver2.5. 实现具体的 DataVisitor2.6. 示例主程序2.7. 编译和运行 0. 引言 使用 C 实现一个类似CyberRT 架构的 …...
TongRDS分布式内存数据缓存中间件
命令 优势 支持高达10亿级的数据缓冲,内存优化管理,避免GC性能劣化。 高并发系统设计,可充分利用多CPU资源实现并行处理。 数据采用key-value多索引方式存储,字段类型和长度可配置。 支持多台服务并行运行,服务之间可互…...
银河麒麟v4/v10 Ubuntu上添加服务过程-以编译postgressql数据库为例
1 首先联网安装依赖 apt-get install build-essential zlib1g-dev libssl-dev libreadline-dev libxml2-dev python-setuptools 2 下载安装包 下载地址:https://ftp.postgresql.org/pub/source/v16.3/postgresql-16.3.tar.gz 3 编译安装 mkdir -p /data/pgsql…...
电子商务人工智能指南 1/6 - 搜索、广告和发现
介绍 81% 的零售业高管表示, AI 至少在其组织中发挥了中等至完全的作用。然而,78% 的受访零售业高管表示,很难跟上不断发展的 AI 格局。 近年来,电子商务团队加快了适应新客户偏好和创造卓越数字购物体验的需求。采用 AI 不再是一…...
JAVA面试基础(总结了很多)
最近帮整理了一份JAVA的面试基础,不过很基础后面还回继续更新。 java的专业技能 2.1 java的基础部分 2.1.1 简单讲一下java的跨平台原理 由于各操作系统(windows,liunx等)支持的指令集,不是完全一致的。就会让我们的程序在不同的操…...
PPT怎样做的更加精美
目录 PPT怎样做的更加精美 3D的GIF图片 3维空间图编辑 结果有明显的对比 阅读高质量文献,采用他们的图 PPT怎样做的更加精美 3D的GIF图片 3维空间图 结果有明显的对比...
postgresql与pgvector安装与使用
环境变量修改 打开 .bashrc 文件进行编辑: vim ~/.bashrc在文件的末尾添加上面的环境变量配置 # 添加 PostgreSQL 可执行文件路径到系统 PATH export PATH/home/....../pg/postgresql-12.4/bin:$PATH# 设置 PostgreSQL 数据目录 export PGDATA/home/....../pg/pos…...
Tomcat,javaweb, servlet , springBoot
在server.xml里配置服务器 <scope>provided</scope>打包的时候,这个jar包不会被打进去,因为tomcat已将封装了这个jar包,没必要要这个...
vue 通过 image-conversion 实现图片压缩
简介 vue项目中,上传图片时如果图片很大,通过 image-conversion 压缩到指定大小 1. 安装依赖 npm i image-conversion --save2. 引用 import * as imageConversion from image-conversion3. 使用 const newFile new Promise((resolve) > {// 压…...
自由学习记录(27)
event委托在类内可完全修改 (前提为该event在类中的声明为public,外部可访问,然后外部访问的时候不能直接改) 下面这段代码是在 类的内部 访问事件 void ClearAllListeners() {MyEvent null; }event 修饰的委托字段 在类内部没…...
MATLAB数学建模之画图汇总
MATLAB是一种强大的数学软件,广泛应用于工程计算、控制设计、信号处理等领域。在数学建模中,MATLAB的绘图功能可以帮助我们直观地展示数据和模型结果。 1. 二维数据曲线图 1.1 绘制二维曲线的基本函数 plot函数用于绘制二维平面上的线性坐标曲线图&am…...
UML箭线图的理解和实践
在软件开发的世界里,UML(统一建模语言)作为一种标准化的建模语言,扮演着举足轻重的角色。UML类图更是软件开发设计和架构过程中的核心工具,它不仅能帮助开发者明确系统中的类及其关系,还能为后续的代码实现…...
最新AI问答创作运营系统(SparkAi系统),GPT-4.0/GPT-4o多模态模型+联网搜索提问+问答分析+AI绘画+管理后台系统
目录 一、人工智能 系统介绍文档 二、功能模块介绍 系统快速体验 三、系统功能模块 3.1 AI全模型支持/插件系统 AI大模型 多模态模型文档分析 多模态识图理解能力 联网搜索回复总结 3.2 AI智能体应用 3.2.1 AI智能体/GPTs商店 3.2.2 AI智能体/GPTs工作台 3.2.3 自…...
C#中的多态
多态(Polymorphism)是面向对象编程中的核心概念之一,它允许对象在不同的上下文中表现出不同的行为。简单来说,多态使得相同的方法调用可以表现出不同的行为,这使得代码更加灵活、可扩展和可维护。 在 C# 中࿰…...
【SQL】实战--组合两个表
题目描述 表: Person ---------------------- | 列名 | 类型 | ---------------------- | PersonId | int | | FirstName | varchar | | LastName | varchar | ---------------------- personId 是该表的主键(具有唯一值的列)…...
Unity 的介绍
Unity是一款功能强大的跨平台游戏开发引擎,以下是关于它的详细介绍: 一、概述 Unity由Unity Technologies公司开发,它提供了一个直观的开发环境,用于创建2D、3D游戏、模拟、虚拟现实(VR)、增强现实&#…...
深度学习的进展
深度学习新纪元 引言 你是否曾想过,为什么智能助手能理解你的指令,数字图像能够被准确分类,甚至疾病能被更早地诊断?这些现代奇迹背后都有一个共同的驱动力——深度学习。它不仅是当今人工智能领域的闪亮明星,更是一…...
vue中实现数字滚动效果
安装vue-count-to npm install vue-count-to引入 vue-count-to <template><div><count-to :start-val"startVal" :end-val"endVal" :duration"duration" :decimals"decimals" :separator"separator" :pref…...
Python的textwrap库:文本包装的艺术
目录 一、初识textwrap 二、textwrap的核心函数 1. fill 2. wrap 3. dedent 4. indent 5. shorten 三、高级用法与技巧 1. 处理特殊字符 2. 自定义断行逻辑 3. 自定义缩进和前缀 四、实战案例 五、总结 在Python编程中,处理文本是一项基础且常见的任务…...
linux 系列服务器 高并发下ulimit优化文档
系统输入 ulimit -a 结果如下 解除或提高 Linux 系统的最大进程数 在高并发场景中,合理设置 Linux 系统的最大进程数对于提升服务器性能至关重要。以下是具体步骤: 临时修改 ulimit 设置 可以通过 ulimit 命令临时调整当前会话的最大进程数。 查看当前…...
Spring03——基于xml的Spring应用
Spring开发中主要对Bean的配置 Bean的常用配置一览如下: Xml配置方式功能描述<bean id"" class"">Bean的id和全限定名配置<bean name"">通过name设置Bean的别名,通过别名也能直接获取到Bean实例<bean sc…...
IDEA 鼠标悬浮显示方法注释 javaDoc 及配置遇到的问题
方法详情: 鼠标悬浮时的效果: 设置方法: File -> Settings -> Editor -> Code Editing -> Quick Documentation,勾选红框中的选项 可能会遇到的问题: 如果不能选中,如下图 把下图的位置的选中项取消掉 选…...
openstack创建浮动IP全过程
1、创建外部网络,即是provider网络,有关provider网络的详细解释请参见我之前的文章openstack中的self-service和provider网络_openstack provider网络不能创建vlan吗-CSDN博客 network create --share --external --provider-physical-network physnet1…...
利用空闲主机进行Nmap隐匿扫描:IP伪造与空闲扫描技术
IP伪造与空闲扫描技术 在网络安全领域,扫描和识别目标主机的开放端口是攻击者获取目标信息的重要手段。传统的扫描方法可能会暴露扫描者的真实IP地址,从而引起目标主机的警觉。然而,IP地址伪造是一种巧妙的方式,可以帮助攻击者在…...
vue聊天对话语音消息播放动态特效
vue2写法,vue3也能用,粘之即走: 示例: <template><div class"voice-hidden"><divclass"voice-play-chat":class"[className, { animate-stop: !isPlaying }]"><div class&q…...
流媒体之linux下离线部署FFmpeg 和 SRS
前言 用户对网络做了限制,只能访问指定的网址,和没网没啥区别,导致无法连接外网,无法获取安装包,还有一些编译需要的开源工具 用户需要用平台查看库房的海康摄像头实时监控,只能在库房里一台纯净的ubantu…...
C/C++内存管理
1. C/C内存分布 我们先来看下面的一段代码和相关问题 const int a(此时an存放在栈上)char char2[] "abcd"(此时是在栈上创建5个char类型大小的数组,并让用常量字符串来初始化数组内的内容,*char2就是数组…...
xiaolin coding 图解 MySQL笔记——锁篇
1. 全局锁是怎么用的? flush tables with read lock 执行以后,整个数据库就处于只读状态了,这时其他线程执行对数据的增删改操作(insert、delete、update);对表结构的更改操作(alter table、dr…...
node.js实现分页和jwt鉴权机制
const express require(express); const jwt require(jsonwebtoken); const app express(); // 模拟数据库 const db { users: [ { id: 1, username: user1, email: user1example.com }, // ...更多用户 ], // ...其他数据模型 }; // 应用中间件 app.use(express.json…...
Issue id: AppLinkUrlError 应用intent-filter 配置深链接 URL 问题分析 | AndroidManifest
AndroidManifest.xml 配置文件中,对 activity 组件进行声明的时候,独立应用在 IDE 显示 intent-filter 报错,但不影响实际编译,因为是系统应用,肯定会有此 URL 的存在。 AOSP 源码: <activity android:…...
STM32F103 PWM配置
在《STM32F103定时器配置》中我们介绍了PWM的产生原理,本节介绍介绍如何编码实现PWM的输出。 一、PWM相关寄存器 TIMx如果要产生PWM,除了我们上一节提到的如下寄存器: 控制寄存器(TIMx_CR1);DMA/中断使能寄存器(TIMx_DIER)&#x…...
C语言蓝桥杯进阶
系列文章目录 文章目录 系列文章目录前言一、题目1、在 ISO 国际标准中定义了 A0 纸张的大小为 1189mm 841mm,将 A0 纸沿长边对折后为 A1 纸,大小为 841mm 594mm,在对折的过程中长度直接取下整(实际裁剪时可能有损耗)…...
【笔记2-2】ESP32:开发板与espidf插件的一些配置项
主要参考b站宸芯IOT老师的视频,记录自己的笔记,老师讲的主要是linux环境,但配置过程实在太多问题,就直接用windows环境了,老师也有讲一些windows的操作,只要代码会写,操作都还好,开发…...
【Linux】线程概念 | 线程控制
文章目录 👉知识补充👈👉Linux线程概念👈什么是线程Makefile线程 VS 进程线程的优点线程的缺点线程异常线程用途 👉线程控制👈线程终止pthread_exit 函数pthread_cancel 函数线程 ID 的深入理解在多线程的场…...
OCR的评价指标和常用数据集
1.OCR任务简介 OCR(Optical Character Recognition,光学字符识别)是指对包含文本内容的图像或者视频进行处理识别,并提取其中所包含的文字及排版信息的过程。例如,一个常见的应用是将包含文档图像的不可编辑状态的 PDF 文档通过 OCR 技术识别后…...
React性能优化
三个可以优化的地方 避免过度多次渲染 组件会在以下情况下重新渲染 注意:例如组件组合的形式,<Test><Counter></Counter></Test>,即使Test发生了重新渲染,Counter也不会重新渲染。另外使用React这样的库或框架时&a…...
Django之ORM
1.ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。 简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对…...
macos上设置windsurf命令行启动
解决方案 1. 在/usr/local/bin 目录下创建软链 sudo ln -s /Applications/Windsurf.app/Contents/Resources/app/bin/windsurf /usr/local/bin/windsurf 2. 执行source source ~/.zshrc...
一、web基础和http协议
前言 https://www.baidu.com/:URL(是一种万维网寻址网址) https://:协议,加密的http,加密的超文本传输协议,在数据传输之前要通过整数进行身份验证,验证通过才可以进行数据传输。 …...
Can‘t find variable: token(token is not defined)
文章目录 例子 1:使用 var例子 2:使用 let 或 const例子 3:异步操作你的代码中的情况 Cant find variable: tokentoken is not defined源代码 // index.jsPage({data: {products:[],cardLayout: grid, // 默认卡片布局为网格模式isGrid: tr…...
Elasticsearch ILM 故障排除:常见问题及修复
作者:来自 Elastic Stef Nestor 大家好!我们的 Elasticsearch 团队正在不断改进我们的索引生命周期管理 (index Lifecycle Management - ILM) 功能。当我第一次加入 Elastic Support 时,我通过我们的使用 ILM 实现自动滚动教程快速上手。在帮…...
1. 设计模式的由来
设计模式的灵感来自建筑师亚历山大的“设计套路”,后来被程序员借用,总结出一套“编程武功秘籍”。 20世纪90年代,四位软件工程师(被称为“四人帮”)——Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides&…...
【Excel】Excel中将日期格式转换为文本格式,并按日期显示。
【问题需求】 在使用excel进行数据导入的过程中, 有的软件要求日期列必须是文本格式。 但是直接将日期列的格式改为文本后,显示一串数字,而不按日期显示。 进而无法导入使用。 【解决方法】 使用【TXET】函数公式进行处理, 在单独…...
SpringBoot入门:如何新建SpringBoot项目(保姆级教程)
在本文中,我们将演示如何新建一个基本的 Spring Boot 项目。写这篇文章的时候我还是很惊讶的,因为我发现有些java的初学者,甚至工作10年的老员工居然并不会新建一个SpringBoot项目,所以特别出了一篇文章来教大家新建一个SpringBoo…...