使用selenium
1、查看Chrome版本去下载浏览器驱动 驱动下载链接
2、selenium官方网站 官方文档
selenium通信原理
- 对于每一条Selenium脚本,一个http请求会被创建并且发送给浏览器的驱动
- 浏览器驱动中包含了一个HTTP Server,用来接收这些http请求
- HTTP Server接收到请求后根据请求来具体操控对应的浏览器
- 浏览器执行具体的测试步骤
- 浏览器将步骤执行结果返回给HTTP Server
- HTTP Server又将结果返回给Selenium的脚本,如果是错误的http代码我们就会在控制台看到对应的报错信息。
那为什么同一个浏览器驱动即可以处理Java语言的脚本,也可以处理Python语言的脚本呢?
这就要提到WebDriver基于的协议:JSON Wire protocol。
1、JSON Wire protocol是在http协议基础上,对http请求及响应的body部分的数据的进一步规范
2、在WebDriver中为了给用户以更明确的反馈信息,提供了更细化的http响应状态码
3、body部分主要传送具体的数据,在WebDriver中这些数据都是以JSON的形式存在并进行传送的
原码分析 WebDriver的结构中就是典型的C/S结构,WebDriver API相当于是客户端,而小小的浏览器驱动才是服务器端。
1、执行webdriver.Chrome() -> 就会去启动一个子进程执行浏览器驱动监听端口号,这个驱动内部实现了一个soket 的server端
2、父类remoteWebDriver中实现了接口提供使用 -》 调用接口最终会执行excute方法去执行
3、excute方法解析好具体的操作 根据http协议去向driver内部的server发起请求
4、浏览器驱动就去执行对应的浏览器执行操作
WebDriver核心方法和属性
1 driver.page_source #网页资源 2 driver.title # 网页标题 3 driver.window_handles # 窗口句柄 4 driver.back() # 后退 5 driver.current_url # 当前url 6 driver.maximize_window() # 窗口最大化 7 driver.fullscreen_window() # 截图 8 driver.get_cookies() #获取cookies
WebElement核心方法和属性
1 ele.get_attribute("name") # 获取元素的name属性 2 driver.find_element_by_tag_name("form").submit() # 表单提交 5 import time 7 from selenium import webdriver 8 9 driver = webdriver.Chrome() 10 driver.get("http://localhost:8000/login/") 11 driver.find_element_by_id("id_name").send_keys("admin") 12 driver.find_element_by_id("id_passwd").send_keys("admin123") 13 driver.find_element_by_name("remember").click() 14 if driver.find_element_by_name("remember").is_selected(): # 查看是否被选中 15 print("记住密码") 16 else: 17 print("位被选中") 18 driver.find_element_by_tag_name("form").submit() # 提交表单 19 20 time.sleep(2) 21 driver.quit()
等待元素出现方式
1、隐性等待 driver.implicitly_wait(10) -> 等待整个document页面元素加载完毕
2、显性等待 WebDriverWait(driver, 10, 0.2).until(EC.presence_of_element_located((By.ID, “myDynamicElement”)))
1 from selenium import webdriver 2 from selenium.webdriver.common.by import By 3 from selenium.webdriver.support.ui import WebDriverWait 4 from selenium.webdriver.support import expected_conditions as EC 5 6 driver = webdriver.Firefox() 7 driver.get("http://somedomain/url_that_delays_loading") 8 try: 9 element = WebDriverWait(driver, 10, 0.2).until( # 每隔0.2秒钟轮询一次,10秒钟元素未出现则会报等待超时 10 EC.presence_of_element_located((By.ID, "myDynamicElement"))) 11 finally: 12 driver.quit()
显性等待源码解析
expected_conditions 提供的方法 (了解即可,使用时查看源码)
1 title_is 标题是某内容 2 title_contains 标题包含某内容 3 presence_of_element_located 节点加载出,传入定位元组,如 (By.ID, 'p') 4 visibility_of_element_located 节点可见,传入定位元组 5 visibility_of 可见,传入节点对象 6 presence_of_all_elements_located 所有节点加载出 7 text_to_be_present_in_element 某个节点文本包含某文字 8 text_to_be_present_in_element_value 某个节点值包含某文字 9 frame_to_be_available_and_switch_to_it frame 加载并切换 10 invisibility_of_element_located 节点不可见 11 element_to_be_clickable 节点可点击 12 staleness_of 判断一个节点是否仍在 DOM,可判断页面是否已经刷新 13 element_to_be_selected 节点可选择,传节点对象 14 element_located_to_be_selected 节点可选择,传入定位元组 15 element_selection_state_to_be 传入节点对象以及状态,相等返回 True,否则返回 False 16 element_located_selection_state_to_be 传入定位元组以及状态,相等返回 True,否则返回 False 17 alert_is_present 是否出现 Alert
案例演示
1 from selenium.webdriver.support import expected_conditions as EC 2 # 案例演示 3 wait = WebDriverWait(driver, 10) 4 element = wait.until(EC.element_to_be_clickable((By.ID, 'someid')))
自定义expected_conditions
窗口句柄相关
1 driver.window_handles:获取浏览器打开的所有窗口句柄 2 3 driver.switch_to_window(browser.window_handles[1]) 切换到对应窗口
ActionChains 鼠标移动、鼠标按钮操作、按键和上下文菜单交互
1、说明
当调用 ActionChains 对象上的操作方法时, 动作存储在 ActionChains 对象的队列中。
当调用 perform() 时,事件会按照它们的顺序触发 正在排队
2、案例
menu = driver.find_element(By.CSS_SELECTOR, ".nav") hidden_submenu = driver.find_element(By.CSS_SELECTOR,".nav #submenu1") ActionChains(driver).move_to_element(menu).click(hidden_submenu).perform()
3、ActionChains提供的常用方法
1 click_and_hold(element) 按住鼠标左键 2 double_click(element) 双击一个元素 3 drag_and_drop(源元素,目标元素) 在源元素上按住鼠标左键,然后移动到目标元素并释放鼠标按钮 4 drag_and_drop_by_offset( 源 , xoffset , yoffset ) 5 move_by_offset( xoffset , yoffset )移动鼠标到x,y坐标 6 move_to_element( element ) 将鼠标移动到元素的中间 7 pause(sec) 等待指定秒数 8 release(element) 释放鼠标 9 scroll( x: int , y: int , delta_x: int , delta_y: int , 持续时间: int = 0 , origin: str = 'viewport' ) 10 将滚轮滚动信息发送到浏览器进行处理。 11 参数: 12 x:起始X坐标 13 y:起始Y坐标 14 delta_x:鼠标在x轴上滚动的距离 15 delta_y:鼠标在y轴上滚动的距离
Alert 提示框 selenium.webdriver.common.alert.Alert 模块
1 接受和关闭警告提示 2 Alert(driver).accept() 3 Alert(driver).dismiss() 4 需要输入值的提示框 5 Alert(driver).send_keys('xxx').accept() 6 获取文本 7 Alert(driver).text 8 案例演示 9 # confirm,alert都是这样的写法 10 al = self.driver.switch_to.alert 11 al.dismiss()
多选下拉框相关操作案例
1 # 下拉框 2 from selenium.webdriver.support.ui import Select 3 sl = driver.find_element_by_id("...") 4 sl.first_selected_option.text // 输出第一个选项的值 5 sl.select_by_index(1) // 通过索引去勾选 6 sl.select_by_value(“笑嘻嘻”) // 通过value属性去勾选 7 sl.select_by_visible_text(“笑嘻嘻”) // 通过options标签中间包着的text值去勾选 8 9 sl.options //返回所有的选项 10 sl.options[0].is_selected() // 是否被勾选 11 sl.all_selected_options // 当前勾选的选项 12 13 sl.deselected_all() // 取消全部选项
无头模式设置
1 # 无头模式 2 # from selenium.webdriver.remote.webelement import WebElement 3 opts = webdriver.ChromeOptions() 4 opts.headless=True 5 driver = Chrome(chrome_options=opts)
滑块操作案例
1 # 滑块拖动案例 2 // 小滑块 3 ele = driver.find_element(..div) 4 x = ele.location['x'] 5 y = ele.location['y'] 6 // 大滑块 7 ele1 = driver.find_element("...") 8 width = ele1.size["width"] 9 ActionChains(driver).drag_and_drop_by_offset(ele,x+width,y).perform()
webelement对象 常用方法 (了解即可,使用时查看源码)
current_url: 获取当前url的一个类属性
get_cookies(): 获取cookies -> 返回[{…}]
page_source: 获取网页资源
webelement.get_attribute(‘class’): 获取属性
webelement.text: 获取元素的文本内容
获取ID、位置、标签名、大小
element.id
element.location
element.tag_name
element.size
driver.switch_to.frame() 切换frame
driver.switch_to.parent_frame() 切换回父frame
diver.forward() 前进
diver.back() 后退
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/283108.html