Selenium框架

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]设置浏览器大小

  • set_window_size() 设置分辨率
from selenium import webdriver
import time

browser = webdriver.Chrome()

# 设置分辨率大小为 500*500
browser.set_window_size(500, 500)
browser.get('https://www.baidu.com')
time.sleep(2)

# 关闭浏览器
browser.close()
  • maximize_window 设置全屏
from selenium import webdriver
import time

browser = webdriver.Chrome()

# 设置浏览器为全屏
browser.maximize_window()
browser.get('https://www.baidu.com')
time.sleep(2)

# 关闭浏览器
browser.close()

[4]前进后退

  • forward()前进
  • back()后退
from selenium import webdriver
import time

browser = webdriver.Chrome()

# 设置浏览器全屏
browser.maximize_window()

# 打开百度页面
browser.get('https://www.baidu.com')
time.sleep(2)

# 打开bilibili页面 每次打开都会覆盖之前的
browser.get('https://www.bilibili.com/')
time.sleep(2)

# 后退到百度页面
browser.back()
time.sleep(2)

# 前进到bilibili页面
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]切换选项卡

  • browser.window_handles : 获取聚柄 默认从0开始

  • switch_to.window(聚柄[索引]) : 切换选项卡

from selenium import webdriver
import time

# 创建 Chrome 浏览器的实例
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

# 切换到第二个选项卡(下标为1)
browser.switch_to.window(all_handles[1])
time.sleep(2)

# 在第二个选项卡中打开jd网页
browser.get('http://www.jd.com')
time.sleep(2)

# 切换回第一个选项卡(下标为0)
browser.switch_to.window(all_handles[0])
time.sleep(2)

# 在第一个选项卡中打开bilibili网页
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

  • 通过元素的 ID 属性进行定位
element = driver.find_element(By.ID, "element_id")

[2]name

  • 通过元素的 Name 属性进行定位
element = bro.find_element(By.NAME, 'element_name')

[3]Class

  • 通过元素的 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

  • 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)元素操作

[1]向input框内输入内容

  • send_keys('')
search_input.send_keys('')

[2]清空内容

  • clear()
search_input.clear()

[3]点击元素操作

  • click()
search_input.click()

[4]获取元素的属性名对应的属性值

  • get_attribute(属性名)
search_input.get_attribute(属性名)

[5]提交操作

  • submit()
search_input.submit()

[2]获取元素的坐标

search_input.location # {'x': 236, 'y': 70}

[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:
    # xoffset 表示水平方向上的偏移量,yoffset 表示垂直方向上的偏移量。

    # xoffset:表示相对于当前鼠标位置的水平方向上的移动距离。
    # 如果xoffset 为正数,鼠标将向右移动;如果xoffset 为负数,鼠标将向左移动;
    # 如果xoffset 为0,则水平方向上不发生移动。
    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()方法实现点击操作。
# 使用JavaScript点击一个按钮
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)拖动元素

  • 首先,获取源元素和目标元素的位置信息,然后创建鼠标事件并分发到源元素上,模拟鼠标按下、移动和松开的动作,从而实现拖动操作。
# 使用JavaScript拖动一个可拖动的元素到目标位置
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方法传递属性名参数来返回对应的属性值。
# 使用JavaScript获取元素的属性值
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

# 初始化WebDriver
browser = webdriver.Chrome()

# 打开京东网页
browser.get('https://www.baidu.com/')

# 获取当前百度热搜所在的标签
top_search = browser.find_element(By.CLASS_NAME, "c-font-medium")
time.sleep(2)

# 获取当前标签的 class 属性值
attribute_value = browser.execute_script('return arguments[0].getAttribute("class");', top_search)
print(attribute_value) # title-text c-font-medium c-color-t

# 获取当前输入框标签
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)
  • 一般情况下不太使用强制等待,主要应用的场景在于不同系统交互的地方。
import time
time.sleep(n)      # 阻塞等待设定的秒数之后再继续往下执行

(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

# 设置WebDriver等待时间为最多10秒,每隔0.5秒检查一次
#每隔 0.5s 检查一次(默认就是 0.5s)
# 最多等待 10 秒,否则报错。
#如果定位到元素则直接结束等待
#如果在10秒结束之后仍未定位到元素则报错
wait = WebDriverWait(chrome, 10, 0.5)

# 等待页面中的元素"J_goodsList"出现
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()

# 携带 cookie 访问京东

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')

# 设置WebDriver等待时间为最多10秒,每隔0.5秒检查一次
# 每隔 0.5s 检查一次(默认就是 0.5s)
# 最多等待 10 秒,否则报错。
# 如果定位到元素则直接结束等待
# 如果在10秒结束之后仍未定位到元素则报错
wait = WebDriverWait(chrome, 10, 0.5)

# 等待页面中的元素"J_goodsList"出现
wait.until(EC.presence_of_element_located((By.ID, 'J_goodsList')))

(3)隐式等待

  • 隐式等待设置之后代码中的所有元素定位都会做隐式等待
  • 通过implicitly Wait完成的延时等待,注意这种是针对全局设置的等待
  • 如设置超时时间为10秒,使用了implicitlyWait后
  • 如果第一次没有找到元素,会在10秒之内不断循环去找元素
  • 如果超过10秒还没有找到,则抛出异常
  • 隐式等待比较智能,它可以通过全局配置,但是只能用于元素定位
driver.implicitly_wait(10)    
# 在指定的n秒内每隔一段时间尝试定位元素,如果n秒结束还未被定位出来则报错

(4)总结

  • 显示等待

  • 原理:显示等待,就是明确要等到某个元素的出现或者是某个元素的可点击等条件,等不到,就一直等,除非在规定的时间之内都没找到,就会跳出异常Exception

  • (简而言之,就是直到元素出现才去操作,如果超时则报异常)

  • 隐式等待

  • 原理:隐式等待,就是在创建driver时,为浏览器对象创建一个等待时间,这个方法是得不到某个元素就等待一段时间,直到拿到某个元素位置。

  • 注意:在使用隐式等待的时候,实际上浏览器会在你自己设定的时间内部断的刷新页面去寻找我们需要的元素

(7)cookie操作

(1)获取cookie

  • get_cookies()
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

# 测试cookie是否有效
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")

# 删除名为 "cookie_name" 的 cookie
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

# 创建 ChromeOptions 实例
chrome_options = Options()

# 指定浏览器分辨率
chrome_options.add_argument('window-size=1920x3000')

# 规避 bug,需要加上这个属性
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')

# 无头模式,不提供可视化页面。在 Linux 下,如果系统不支持可视化,不加这条会启动失败
# chrome_options.binary_location = r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"

# 手动指定
# 创建 Chrome WebDriver 实例,并传入配置参数
driver = webdriver.Chrome(options=chrome_options)
driver.get('https://www.baidu.com')  # 打开百度首页

# 在页面源代码中查找关键词 'hao123' 并打印结果
print('hao123' in driver.page_source)
# True

driver.close()  # 关闭浏览器窗口,释放资源
posted @ 2024-04-08 12:02  ssrheart  阅读(9)  评论(0编辑  收藏  举报