PythonUI自动化Selenium库解说

前言:了解一下Selenium包括一系列的工具组件

Selenium IDE:是嵌入到FireFox浏览器的插件,用于在Firefox上录制和回放Selenium脚本;虽然只能在Firefox下使用,但它能将录制好的脚本转换成各种Selenium WebDriver支持的程序语言,进而扩展到更广泛的浏览器类型;

2.Selenium WebDriver:可支持多种语言,用于操作浏览器的一套API;支持各类型浏览器,跨操作系统;WebDriver为诸多语言提供完备的,用于实现web自动化测试的第三方库;

3.Selenium Standalone Server:包括Selenium Grid、远程控制、分布式部署等,可实现Selenium脚本的高效执行与拓展;

利用Grid使得自动化测试可以并行运行,甚至在跨平台、异构的环境中运行,包括主流的移动端如Android、iOS;

学习准备:Python语言及语法,至于一些前期准备和环境配置,我们稍后来实践;

这里我主要讲解一下基于Python的Selenium WebDriver,Selenium可以自动操纵浏览器来做很多,如模拟与浏览器的交互,而且支持到多数主流浏览器;编写自动化脚的语言需要有Selenium client library支持所以选择Python

一、环境搭建

去官网下载Python安装包https://www.python.org/
配置Python环境,这里安装的时候可以选择部署Path
如果没有添加成功手动在系统环境变量添加python安装根目录及根目录下的scripts目录
WIN7用户Path下面添加相对变量这里添加Python_HOME变量Python_HOME 值:C:\Python37 及在Path变量后添加以下内容
Path %Python_HOME\%;%Python_HOME\Scripts\%;
WIN10用户就只能绝对路径C:\Python37\Scripts\;C:\Python37\;
下载浏览器的驱动程序http://chromedriver.storage.googleapis.com/index.html
把exe文件存放到任意系统环境目录下,建议存放在python安装根目录或scripts目录
之后执行终端命令:pip3 install -U selenium  这里也可以是pip install selenium
安装Selenium:使用pip工具https://pip.pypa.io/en/latest/ 按照文档需要先执行脚本get-pip.py 

PIP如果下载太慢的话借鉴这篇博客进行优化https://blog.csdn.net/qq_38795430/article/details/94334764

下面是对应Chrom浏览器的兼容驱动版本号

------------2019年兼容版本对照表-----------
注:支持chromeV74版本的driver版本号比较特别一点
ChromeDriver 76.0.3809.12 (2019-06-07)---------Supports Chrome version 76
ChromeDriver 75.0.3770.8 (2019-04-29)---------Supports Chrome version 75
ChromeDriver v74.0.3729.6 (2019-03-14)--------Supports Chrome v74
ChromeDriver v2.46 (2019-02-01)----------Supports Chrome v71-73
--------以下为2018年兼容版本对照表-------
ChromeDriver v2.45 (2018-12-10)----------Supports Chrome v70-72
ChromeDriver v2.44 (2018-11-19)----------Supports Chrome v69-71
ChromeDriver v2.43 (2018-10-16)----------Supports Chrome v69-71
ChromeDriver v2.42 (2018-09-13)----------Supports Chrome v68-70
ChromeDriver v2.41 (2018-07-27)----------Supports Chrome v67-69
ChromeDriver v2.40 (2018-06-07)----------Supports Chrome v66-68
ChromeDriver v2.39 (2018-05-30)----------Supports Chrome v66-68
ChromeDriver v2.38 (2018-04-17)----------Supports Chrome v65-67
ChromeDriver v2.37 (2018-03-16)----------Supports Chrome v64-66
ChromeDriver v2.36 (2018-03-02)----------Supports Chrome v63-65
ChromeDriver v2.35 (2018-01-10)----------Supports Chrome v62-64

二、Selenium库的解析(熟悉一门库或者类需要从开发者的角度看问题)

查找一个元素的其它一些方法(方法不同,查找所需的参数也不同)这里尽量找唯一值下面说一下属性的方法
通过id的属性来查找元素
driver.find_element_by_id()
通过name属性查找元素
driver.find_element_by_name()
通过class属性查找元素
driver.find_element_by_class_name()
通过a标签的文字来查找元素
driver.find_element_by_link_text()
driver.find_element_by_partial_link_text()
通过标签的名字去查找元素
driver.find_element_by_tag_name("")
通过xpath的方法查找元素
driver.find_element_by_xpath("xpath的内容")

再来讲讲另外一种查找元素的方法Xpath

xpath的基本句式
//表示在整个页面中查找内容
//标签名
//标签名[@属性名]
//标签名[@属性名='属性值']
//input[@id='kw']
1.通过属性的多种组合来查找
基本格式://标签名[@属性1='值' and @属性2='值'...]
举例://a[@class='mnav' and @href='http://map.baidu.com']
2.通过元素的序号来查找
//标签名[@属性='值'][序号]
//a[@class='mnav'][4]
3.通过标签的文本值来查找元素
//标签[text()='文本']
//i[text()='玄幻']
5.通过标签的部分文本值来模糊查找元素
.表示普通的文本文字
//标签[contains(.,'部分文本值')]
//p[contains(.,'李辟尘')]
//a[contains(@href,'1055555555')]
6.通过元素的父子级关系来查找元素
//父级/子级
//div[@id='free-type-tab']/ul/li[1]
//span[text()='ECS000134']/../../td/a/img[@src='images/icon_trash.gif']

selenium 在爬取网页时可能会有一些Ajax请求之类的,而selenium不会管你是否完成了网页的加载,他只负责加载框架

1> 隐式等待
当使用了隐式等待执行测试的时候,如果 WebDriver没有在 DOM中找到元素,将继续等待,超出设定时间后则抛出找不到元素的异常, 换句话说当查找元素或元素并没有立即出现的时候,隐式等待将等待一段时间再查找 DOM,默认的时间是0
一般不会用隐式等待,网页加载速度都很快,只有在网速比较慢时使用。
使用implicitly_wait()来进行等待操作,参数为需要等待的时间,默认为0
2> 显式等待(常用)
特点: 指定一个等待条件,再指定一个最长等待时间,他会在最长等待时间内判断这个条件是否成立,不管成立还是不满足这个条件,他就会抛出异常,如果在时间  内满足条件就会返回
一些常见的等待条件:
* title_is 标题是某内容
* title_contains  标题包含某内容
* presence_of_element_located 元素加载出,传入定位元组,如(By.ID, 'p')
* visibility_of_element_located  元素可见,传入定位元组
* visibility_of 可见,传入元素对象
* presence_of_all_elements_located 所有元素加载出
* text_to_be_present_in_element 某个元素文本包含某文字
* text_to_be_present_in_element_value  某个元素值包含某文字
* frame_to_be_available_and_switch_to_it  frame加载并切换
* invisibility_of_element_located 元素不可见
* element_to_be_clickable  元素可点击
* staleness_of  判断一个元素是否仍在DOM,可判断页面是否已经刷新
* element_to_be_selected  元素可选择,传元素对象
* element_located_to_be_selected  元素可选择,传入定位元组
* element_selection_state_to_be  传入元素对象以及状态,相等返回True,否则返回False
* element_located_selection_state_to_be  传入定位元组以及状态,相等返回True,否则返回False
* alert_is_present 是否出现Alert

浏览器的前进和后退(back()、forward())

driver.back() 后退
driver.forward() 前进
driver.refresh() 刷新
那么什么时候会用呢?一种情况就是,当你从一个父页面跳转到子页面进行操作,操作完之后没有“返回”之类的按钮或链接,重新进入父页面又很麻烦,back()可以帮你。forward()与此类似,相对没有back()那么常用。
当你修改了页面信息但是没有即时刷新时,可以手动refresh()

浏览器的鼠标操作ActionChains

action = ActionChains(浏览器)
action.click()           单击
action.double_click()    双击
action.context_click()   右键点击
action.move_to_element() 移动到某个元素上
action.click_and_hold()  按住不动
action.release()         松开鼠标
action.drag_and_drop()   拖住并且移动
action.drag_and_drop_by_offset()  用坐标系来拖动
action.send_keys()       用鼠标来发送文字信息
action.perform()   执行鼠标保存的动作链
action.reset_actions()  重置鼠标保存的所有动作
cannot focus element   
无法聚焦到元素上面
出现原因:有个不标准的输入框需要输入信息
解决办法:使用鼠标点击这个元素,然后用鼠标来完成输入

进入到子页面中:
浏览器.switch_to.frame(iframe标签元素的位置)

返回父级页面:
浏览器.switch_to.parent_frame()

直接返回到最外层的页面:
浏览器.switch_to.default_content()

当中可能有些元素存在不稳定怎么办?

用时间换取稳定,在不稳定的步骤上面,添加强制等待时间
time.sleep()

智能等待:
可以设置最长的等待期限,如果等待了要操作的元素,那么就马上执行
from selenium.webdriver.support.wait import WebDriverWait

语法格式:WebDriverWait(浏览器,最长等待时间).until(lambda x:x.find_element_by_方法()).操作()
举例:WebDriverWait(driver,20).until(lambda x:x.find_element_by_id("kw")).send_keys("hello")

三、带入项目走一下

先说一下需要导入的常用方法

#导入自动化的模块
from selenium import webdriver
#导入时间模块
import time
#导入鼠标的操作模块
from selenium.webdriver.common.action_chains import ActionChains
#导入智能等待模块
from selenium.webdriver.support.wait import WebDriverWait
#导入下拉框模块
from selenium.webdriver.support.select import Select

简单的初始化并打开浏览器窗口的例子

#coding=utf-8
#导入自动化的模块
from selenium import webdriver
#选择打开你要使用的浏览器
driver = webdriver.Chrome()
# 用浏览器打开某个网站
driver.get("https://www.baidu.com/")
# 把这个浏览器窗口最大化
driver.maximize_window()
# 添加浏览器页面的全局等待时间
driver.implicitly_wait(5)

简单的查找元素并进行操作的列子

#coding=utf-8
#导入自动化的模块
from selenium import webdriver
#选择打开你要使用的浏览器
driver = webdriver.Chrome()
# 用浏览器打开某个网站
driver.get("https://www.baidu.com/")
# 把这个浏览器窗口最大化
driver.maximize_window()
# 添加浏览器页面的全局等待时间
driver.implicitly_wait(5)
# 查找输入框,然后输入点什么东西
driver.find_element_by_id("kw").send_keys("helloworld")

采用PO自动化思路进行方法封装

#coding=utf-8
from selenium import webdriver
from selenium.webdriver.support.select import Select
import SendKeys
import time
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.wait import WebDriverWait
import datetime

#需要把driver定义成全局变量
driver = webdriver.Chrome()

#打开浏览器的操作
def open_browser(url,t=10):
    driver.maximize_window()
    driver.implicitly_wait(t)
    driver.get(url)

#查找和定位元素的操作,method是定位的方法,value是定位的位置和内容
def find_element(method,value):
    #先判断用户选择了哪一种定位方法
    try:
        if method=="id":
            ele = WebDriverWait(driver,5).until(lambda x:x.find_element_by_id(value))
        elif method=="name":
            ele = WebDriverWait(driver,5).until(lambda x:x.find_element_by_name(value))
        elif method=="xpath":
            ele = WebDriverWait(driver,5).until(lambda x:x.find_element_by_xpath(value))
        elif method=="link":
            ele = WebDriverWait(driver,5).until(lambda x:x.find_element_by_link_text(value))
        else:
            print "now, we don't have this method!!!"
    except Exception:
        name = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
        driver.get_screenshot_as_file("D:/test/%s.png"%(name))
        return None
    else:
        return ele

#对元素进行输入的操作
def input_(method,value,data):
    ele = find_element(method,value)
    if ele != None:
        ele.clear()
        ele.send_keys(data)
    else:
        print "Input Error: method:%s , value:%s . is not exists!!!"%(method,value)

#对元素进行点击的操作
def click_(method,value):
    ele = find_element(method,value)
    if ele != None:
        ele.click()
    else:
        print "Click Error: method:%s , value:%s . is not exists!!!"%(method,value)

def select_(method,value,data):
    ele = find_element(method,value)
    if ele != None:
        s = Select(ele)
        s.select_by_value(data)
    else:
        print "Select Error: method:%s , value:%s . is not exists!!!"%(method,value)

def js_(data):
    driver.execute_script(data)

def keys_(data):
    SendKeys.SendKeys(data)

def move_(method,value):
    action = ActionChains(driver)
    ele = find_element(method,value)
    if ele != None:
        action.move_to_element(ele)
        action.perform()
        action.reset_actions()
    else:
        print "Move Error: method:%s , value:%s . is not exists!!!"%(method,value)

#对子页面的切换进行操作
def frame_(status,method=None,value=None):
    if status=="frame":
        ele = find_element(method,value)
        if ele != None:
            driver.switch_to.frame(ele)
        else:
            print "Frame Error: method:%s , value:%s . is not exists!!!"%(method,value)
    elif status=="parent":
        driver.switch_to.parent_frame()
    elif status=="default":
        driver.switch_to.default_content()
    else:
        print "now, we don't have this method!!!"

使用方法如下

#coding=utf-8
from PO import *
import unittest
open_browser('https://baidu.com')
input_("id","kw").send_keys("helloworld")
if __name__=="__main__":
    unittest.main()

后续还会继续讲解下拉框/JS/Cookies用于需要登录的一些网址时,可以保持登录状态以及异常处理之类的操作

发布了35 篇原创文章 · 获赞 16 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/qq_38795430/article/details/97576233