Selenium框架
- Selenium是一个自动化测试工具,用于模拟用户在Web应用程序上的操作。它提供了多种编程语言的接口,如Python、Java等,使测试人员能够编写自动化测试脚本。Selenium可以模拟用户在不同浏览器上的操作,包括点击、输入文本等,以验证Web应用程序的功能和性能。它还支持分布式测试和集成到持续集成系统中,使软件开发过程更加高效。
(1)简单操作
[1]初始化浏览器对象
| from selenium import webdriver |
| |
| browser = webdriver.Chrome() |
| browser.close() |
| from selenium import webdriver |
| |
| path = r'./chromedriver' |
| browser = webdriver.Chrome() |
| browser.close() |
[2]访问页面
| from selenium import webdriver |
| import time |
| |
| driver = webdriver.Chrome() |
| driver.get('https://www.jd.com') |
| time.sleep(5) |
[3]设置浏览器大小
| from selenium import webdriver |
| import time |
| |
| browser = webdriver.Chrome() |
| |
| |
| browser.set_window_size(500, 500) |
| browser.get('https://www.baidu.com') |
| time.sleep(2) |
| |
| |
| browser.close() |
| from selenium import webdriver |
| import time |
| |
| browser = webdriver.Chrome() |
| |
| |
| browser.maximize_window() |
| browser.get('https://www.baidu.com') |
| time.sleep(2) |
| |
| |
| browser.close() |
[4]前进后退
| from selenium import webdriver |
| import time |
| |
| browser = webdriver.Chrome() |
| |
| |
| browser.maximize_window() |
| |
| |
| browser.get('https://www.baidu.com') |
| time.sleep(2) |
| |
| |
| browser.get('https://www.bilibili.com/') |
| time.sleep(2) |
| |
| |
| browser.back() |
| time.sleep(2) |
| |
| |
| browser.forward() |
| time.sleep(2) |
| |
| |
| browser.close() |
[5]获取页面基础属性
browser.title
: 获取网页标题
browser.current_url
: 获取当前访问的网址
browser.name
: 获取当前浏览器的名称
browser.page_source
: 获取当前网页的源码
| from selenium import webdriver |
| |
| |
| browser = webdriver.Chrome() |
| |
| |
| browser.get('https://www.baidu.com') |
| |
| |
| print(browser.title) |
| |
| |
| print(browser.current_url) |
| |
| |
| print(browser.name) |
| |
| |
| print(browser.page_source) |
[6]切换选项卡
| from selenium import webdriver |
| import time |
| |
| |
| browser = webdriver.Chrome() |
| |
| |
| browser.get('https://www.baidu.com/') |
| time.sleep(2) |
| |
| |
| browser.execute_script('window.open()') |
| time.sleep(2) |
| |
| |
| all_handles = browser.window_handles |
| |
| |
| browser.switch_to.window(all_handles[1]) |
| time.sleep(2) |
| |
| |
| browser.get('http://www.jd.com') |
| time.sleep(2) |
| |
| |
| browser.switch_to.window(all_handles[0]) |
| time.sleep(2) |
| |
| |
| browser.get('http://www.bilibili.com') |
| time.sleep(2) |
| |
| browser.close() |
| browser.quit() |
(2)定位页面元素
(1)八大选择器介绍
- 通过webdriver对象的 find_element(by=“属性名”, value=“属性值”),主要包括以下这八种。
属性 |
函数 |
CLASS |
find_element(by=By.CLASS_NAME, value='') |
XPATH |
find_element(by=By.XPATH, value='') |
LINK_TEXT |
find_element(by=By.LINK_TEXT, value='') |
PARTIAL_LINK_TEXT |
find_element(by=By.PARTIAL_LINK_TEXT, value='') |
TAG |
find_element(by=By.TAG_NAME, value='') |
CSS |
find_element(by=By.CSS_SELECTOR, value='') |
ID |
find_element(by=By.ID, value='') |
| from selenium.webdriver.common.by import By |
(2)示例
[1]ID
| element = driver.find_element(By.ID, "element_id") |
[2]name
| element = bro.find_element(By.NAME, 'element_name') |
[3]Class
| element = bro.find_element(By.CLASS_NAME, 'element_class') |
[4]Tag定位
| elements = bro.find_elements(By.TAG_NAME, 'div') |
[5]Link文字
| element = bro.find_element(By.LINK_TEXT, 'link_text') |
[6]Partial Link文字
| element = bro.find_element(By.PARTIAL_LINK_TEXT, 'partial_link_text') |
[7]XPath
| element = bro.find_element(By.XPATH, 'xpath_expression') |
[8]CSS选择器
| element = bro.find_element(By.CSS_SELECTOR, 'css_selector') |
(3)百度案例
| from selenium import webdriver |
| from selenium.webdriver.common.by import By |
| |
| browser = webdriver.Chrome() |
| |
| browser.get('https://www.baidu.com/s?wd=xpath') |
| |
| li_list = browser.find_elements(by=By.XPATH,value='/html/body/div[3]/div[5]/div[1]/div[1]/table/tbody/tr/td/div[1]/div[1]/div/section/div[2]/div[1]/div/section[1]/div') |
| for i in li_list: |
| print(i.text) |
(3)元素操作
| search_input.send_keys('') |
[2]清空内容
[3]点击元素操作
[4]获取元素的属性名对应的属性值
| search_input.get_attribute(属性名) |
[5]提交操作
[2]获取元素的坐标
[6]jd案例输入提交
| import time |
| |
| from selenium import webdriver |
| from selenium.webdriver.common.by import By |
| |
| browser = webdriver.Chrome() |
| |
| browser.get('https://www.jd.com') |
| |
| search_input = browser.find_element(By.XPATH, '/html/body/div[1]/div[4]/div/div[2]/div/div[2]/input') |
| |
| search_input.send_keys('手机') |
| time.sleep(3) |
| |
| search_input.clear() |
| time.sleep(3) |
| |
| search_input.send_keys('苹果') |
| time.sleep(3) |
| |
| submit_btn = browser.find_element(By.XPATH, '/html/body/div[1]/div[4]/div/div[2]/div/div[2]/button') |
| submit_btn.click() |
| time.sleep(3) |
| |
| browser.close() |
(4)动作链
(1)模拟鼠标操作
| from selenium.webdriver.common.action_chains import ActionChains |
操作 |
函数 |
鼠标左击 |
click() |
鼠标右击 |
context_click() |
鼠标双击 |
double_click() |
鼠标拖拽 |
drag_and_drop |
鼠标悬停 |
move_to_element() |
鼠标移动到指定位置 |
move_by_offset(xoffset,yoffset) |
鼠标释放 |
release() |
鼠标按住不放 |
click_and_hold(元素) |
执行 |
perform() |
(2)模拟键盘操作
| from selenium.webdriver.common.keys import Keys |
操作 |
函数 |
删除键 |
send_keys(Keys.BACK_SPACE) |
空格键 |
send_keys(Keys.SPACE) |
制表键 |
send_keys(Keys.TAB) |
回退键 |
send_keys(Keys.ESCAPE) |
回车 |
send_keys(Keys.ENTER) |
全选 |
send_keys(Keys.CONTRL,'a') |
复制 |
send_keys(Keys.CONTRL,'c') |
剪切 |
send_keys(Keys.CONTRL,'x') |
粘贴 |
send_keys(Keys.CONTRL,'v') |
(3)jd使用案例
| from selenium import webdriver |
| from selenium.webdriver.common.action_chains import ActionChains |
| from selenium.webdriver.common.by import By |
| from selenium.webdriver.common.keys import Keys |
| import time |
| |
| browser = webdriver.Chrome() |
| browser.get('https://www.jd.com') |
| |
| action = ActionChains(browser) |
| |
| search_input = browser.find_element(By.XPATH, '/html/body/div[1]/div[4]/div/div[2]/div/div[2]/input') |
| |
| search_input.send_keys('手机') |
| time.sleep(3) |
| search_input.send_keys(Keys.CONTROL, 'a') |
| time.sleep(3) |
| |
| search_input.send_keys(Keys.CONTROL, 'c') |
| time.sleep(3) |
| |
| search_input.clear() |
| time.sleep(3) |
| |
| search_input.send_keys(Keys.CONTROL, 'v') |
| time.sleep(3) |
| |
| submit_btn = browser.find_element(By.XPATH, '/html/body/div[1]/div[4]/div/div[2]/div/div[2]/button') |
| |
| action.drag_and_drop(search_input, submit_btn).click().perform() |
| time.sleep(3) |
| |
| browser.close() |
(4)iframe拖拽案例
| from selenium import webdriver |
| from selenium.webdriver.common.action_chains import ActionChains |
| from selenium.webdriver.common.by import By |
| from selenium.webdriver.common.keys import Keys |
| import time |
| |
| browser = webdriver.Chrome() |
| browser.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable') |
| browser.maximize_window() |
| |
| browser.switch_to.frame('iframeResult') |
| old = browser.find_element(By.ID, 'draggable') |
| target = browser.find_element(By.ID, 'droppable') |
| |
| |
| ActionChains(browser).click_and_hold(old).perform() |
| |
| |
| distance = target.location['x'] - old.location['x'] |
| |
| track = 0 |
| while track < distance: |
| |
| |
| |
| |
| |
| ActionChains(browser).move_by_offset(xoffset=5, yoffset=0).perform() |
| track += 5 |
| |
| |
| ActionChains(browser).release().perform() |
| |
| |
| time.sleep(10) |
| |
| browser.close() |
(5)执行js代码
-
execute_script()
-
selenium并不是万能的,有时候页面上操作无法实现的,这时候就需要借助JS来完成了当页面上的元素超过一屏后,想操作屏幕下方的元素,是不能直接定位到,会报元素不可见的。
-
当页面上的元素超过一屏后,想操作屏幕下方的元素,是不能直接定位到,会报元素不可见的。
-
这时候需要借助滚动条来拖动屏幕,使被操作的元素显示在当前的屏幕上。
(1)滚动到页面底部
window.scrollTo(0, document.body.scrollHeight)
| import time |
| from selenium import webdriver |
| |
| browser = webdriver.Chrome() |
| |
| browser.get('https://www.jd.com/') |
| |
| browser.execute_script('window.scrollTo(0, document.body.scrollHeight)') |
| |
| time.sleep(3) |
(2)点击
arguments[0].click();
arguments[0]
表示传递给JavaScript脚本的第一个参数(即element
),通过调用click()
方法实现点击操作。
| |
| element = browser.find_element(By.ID,'button_id') |
| browser.execute_script('arguments[0].click();', element) |
(3)输入文本
arguments[0].value = arguments[1];
arguments[0]
表示传递给JavaScript脚本的第一个参数(即element
),通过将value
属性设置为arguments[1]
来输入文本。
| element = browser.find_element(By.ID,'input_id') |
| text = 'Hello, World!' |
| browser.execute_script('arguments[0].value = arguments[1];', element, text) |
(4)拖动元素
- 首先,获取源元素和目标元素的位置信息,然后创建鼠标事件并分发到源元素上,模拟鼠标按下、移动和松开的动作,从而实现拖动操作。
| |
| source_element = browser.find_element(By.ID,'source_element_id') |
| target_element = browser.find_element(By.ID,'target_element_id') |
| browser.execute_script(''' |
| 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); |
| ''', source_element, target_element) |
(5)获取元素属性
- 这里使用
getAttribute
方法传递属性名参数来返回对应的属性值。
| |
| element = browser.find_element(By.ID,'element_id') |
| attribute_value = browser.execute_script('return arguments[0].getAttribute("attribute_name");', element) |
| print(attribute_value) |
(6)案例
| import time |
| from selenium import webdriver |
| from selenium.webdriver.common.by import By |
| |
| |
| browser = webdriver.Chrome() |
| |
| |
| browser.get('https://www.baidu.com/') |
| |
| |
| top_search = browser.find_element(By.CLASS_NAME, "c-font-medium") |
| time.sleep(2) |
| |
| |
| attribute_value = browser.execute_script('return arguments[0].getAttribute("class");', top_search) |
| print(attribute_value) |
| |
| |
| input_text = browser.find_element(By.ID, "kw") |
| |
| search_text = "Python" |
| |
| browser.execute_script('arguments[0].value = arguments[1];', input_text, search_text) |
| time.sleep(2) |
| |
| |
| search_btn = browser.find_element(By.ID, "su") |
| |
| browser.execute_script('arguments[0].click();', search_btn) |
| |
| time.sleep(2) |
| |
| browser.close() |
(6)页面等待
- 如果网站采用了动态html技术,那么页面上的部分元素出现时间便不能确定,
- 这个时候就可以设置一个等待时间,强制等待指定时间
- 等待结束之后进行元素定位,如果还是无法定位到则报错
(1)强制等待
- 也叫线程等待, 通过线程休眠的方式完成的等待
- 如等待5秒: Thread sleep(5000)
- 一般情况下不太使用强制等待,主要应用的场景在于不同系统交互的地方。
(2)显式等待
- 也称为智能等待,针对指定元素定位指定等待时间
- 在指定时间范围内进行元素查找,找到元素则直接返回
- 如果在超时还没有找到元素,则抛出异常
- 显示等待是 selenium 当中比较灵活的一种等待方式,他的实现原理其实是通过 while 循环不停的尝试需要进行的操作。
| from selenium.webdriver.common.keys import Keys |
| 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(chrome, 10, 0.5) |
| |
| |
| wait.until(EC.presence_of_element_located((By.ID, 'J_goodsList')) |
| from selenium import webdriver |
| from selenium.webdriver.common.keys import Keys |
| from selenium.webdriver.common.by import By |
| from selenium.webdriver.support.ui import WebDriverWait |
| from selenium.webdriver.support import expected_conditions as EC |
| |
| chrome = webdriver.Chrome() |
| |
| |
| |
| cookies = "" |
| |
| cookie_dict = {cookie.split("=", 1)[0].strip(): cookie.split("=", 1)[1].strip() for cookie in |
| [cookie for cookie in cookies.split(";")]} |
| |
| chrome.get('https://search.jd.com/Search?keyword=%E6%89%8B%E6%9C%BA') |
| for name, value in cookie_dict.items(): |
| chrome.add_cookie({'name': name, 'value': value}) |
| |
| chrome.get('https://search.jd.com/Search?keyword=%E6%89%8B%E6%9C%BA') |
| |
| |
| |
| |
| |
| |
| wait = WebDriverWait(chrome, 10, 0.5) |
| |
| |
| wait.until(EC.presence_of_element_located((By.ID, 'J_goodsList'))) |
(3)隐式等待
- 隐式等待设置之后代码中的所有元素定位都会做隐式等待
- 通过implicitly Wait完成的延时等待,注意这种是针对全局设置的等待
- 如设置超时时间为10秒,使用了implicitlyWait后
- 如果第一次没有找到元素,会在10秒之内不断循环去找元素
- 如果超过10秒还没有找到,则抛出异常
- 隐式等待比较智能,它可以通过全局配置,但是只能用于元素定位
| driver.implicitly_wait(10) |
| |
(4)总结
-
显示等待
-
原理:显示等待,就是明确要等到某个元素的出现或者是某个元素的可点击等条件,等不到,就一直等,除非在规定的时间之内都没找到,就会跳出异常Exception
-
(简而言之,就是直到元素出现才去操作,如果超时则报异常)
-
隐式等待
-
原理:隐式等待,就是在创建driver时,为浏览器对象创建一个等待时间,这个方法是得不到某个元素就等待一段时间,直到拿到某个元素位置。
-
注意:在使用隐式等待的时候,实际上浏览器会在你自己设定的时间内部断的刷新页面去寻找我们需要的元素
(7)cookie操作
(1)获取cookie
| tag_url = 'https://dig.chouti.com/' |
| browser = webdriver.Chrome() |
| cookies = browser.get_cookies() |
(2)添加cookie
add_cookie()
- 用for循环给browser对象添加cookie,然后刷新即登录
| def read_cookie(): |
| BASE_DIR = os.path.dirname(__file__) |
| cookie_path = os.path.join(BASE_DIR, 'cookies.json') |
| with open(cookie_path, 'r', encoding='utf8') as f: |
| cookies = json.load(f) |
| return cookies |
| |
| |
| def test_cookie(): |
| browser.get(tag_url) |
| cookie = read_cookie() |
| for ck in cookie: |
| browser.add_cookie(ck) |
| |
| browser.refresh() |
| time.sleep(3) |
(3)删除cookie
delete_cookie(name)
: 删除指定键的cookie
delete_all_cookies()
: 删除所有的cookie
| from selenium import webdriver |
| browser = webdriver.Chrome() |
| browser.get("https://example.com") |
| |
| |
| browser.delete_cookie("cookie_name") |
| |
| browser.quit() |
(4)cookie中键名的含义
| name cookie的名称 |
| value cookie对应的值,动态生成的 |
| domain 服务器域名 |
| expiry Cookie有效终止日期 |
| path Path属性定义了Web服务器上哪些路径下的页面可获取服务器设置的Cookie |
| httpOnly 防脚本攻击 |
| secure 在Cookie中标记该变量,表明浏览器和服务器之间的通信协议为加密认证协议。 |
(8)无头浏览器
- 无头浏览器,即 Headless Browser,是一种没有界面的浏览器。
- 它拥有完整的浏览器内核,包括 JavaScript 解析引擎、渲染引擎等。
- 与普通浏览器最大的不同是,无头浏览器执行过程中看不到运行的界面,但是我们依然可以用 GUI 测试框架的截图功能截取它执行中的页面。
- 无头浏览器主要应用在: GUI 自动化测试、页面监控、网络爬虫以及没有桌面的linux系统中。
(1)浏览器的渲染机制
- 这里总结一下浏览器如何渲染网页,简单的说浏览器的渲染机制可以分为五步:
- 第一步:解析html,构建DOM树
- 第二步:解析CSS,生成CSSOM树
- 第三步:合并dom树和css规则树,生成render渲染树
- 第四步:根据render渲染树进行布局
- 第五步:调用GPU对渲染树进行绘制,合成图层,显示在屏幕上
- 在这里就可以看出,当无头浏览器不做渲染时,速度显然会提升很多!
(2)案例
| from selenium import webdriver |
| from selenium.webdriver.chrome.options import Options |
| |
| |
| chrome_options = Options() |
| |
| |
| chrome_options.add_argument('window-size=1920x3000') |
| |
| |
| chrome_options.add_argument('--disable-gpu') |
| |
| |
| chrome_options.add_argument('--hide-scrollbars') |
| chrome_options.add_argument('blink-settings=imagesEnabled=false') |
| |
| |
| chrome_options.add_argument('--headless') |
| |
| |
| |
| |
| |
| |
| driver = webdriver.Chrome(options=chrome_options) |
| driver.get('https://www.baidu.com') |
| |
| |
| print('hao123' in driver.page_source) |
| |
| |
| driver.close() |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?