Selenium Python

1. 什么是Selenium

  Selenium是一个免费的(开源)自动化测试组件,适用于跨不同浏览器和平台的Web应用程序。它非常类似于HP Quick Test Pro (QTP现在叫UFT),只是Selenium侧重于自动化基于Web的应用程序。使用Selenium工具进行的测试通常称为Selenium测试。

Selenium的组成

整个Selenium工具套件由四个组件组成:

Selenium IDE,一个Firefox插件,您只能在创建相对简单的测试用例和测试套件时使用它。
Selenium RC,也称为Selenium 1,它是第一个允许用户使用编程语言创建复杂测试的Selenium工具。
WebDriver是一个新的突破,它允许您的测试脚本直接与浏览器通信,从而从操作系统级别控制它。
Selenium Grid也是一个工具,它与Selenium RC一起用于跨不同的浏览器和操作系统执行并行测试。
Selenium RC与WebDriver合并形成Selenium 2,现已经更新到了Selenium 3 和Selenium 4。

Selenium的优点

Selenium在成本和灵活性方面比QTP更有优势。它还允许您并行地运行测试,而不像在QTP中,您只允许顺序地运行测试。

    • 成本(因为Selenium是完全免费的)
    • 灵活性(因为Selenium可以支持多种编程语言、浏览器和平台)
    • 并行测试(这是QTP能够做到的,但只有使用质量中心)

Quick Test Professional(QTP)是一种专有的自动化测试工具,在2006年被惠普收购之前,它曾属于Mercury Interactive公司。

2. Selenium3 浏览器驱动

下载浏览器驱动

下载Driver要注意和你当前已有的浏览器的版本是否一致

Chrome浏览器驱动:chromedriver 

IE浏览器驱动:IEDriverServer

Edge浏览器驱动:MicrosoftWebDriver

设置浏览器驱动

我的电脑-->属性-->系统设置-->高级-->环境变量-->系统变量-->Path,将存放浏览器驱动的目录添加到Path的值中。

或者 浏览器驱动放到与python.exe同级目录中

3. selenium元素定位

  Selenium提供了8种定位方式。

  1. id
  2. name
  3. class name
  4. tag name
  5. link text
  6. partial link text
  7. xpath
  8. css selector

  这8种定位方式在Python selenium中所对应的方法为:

  1. find_element_by_id()
  2. find_element_by_name()
  3. find_element_by_class_name()
  4. find_element_by_tag_name()
  5. find_element_by_link_text()
  6. find_element_by_partial_link_text()
  7. find_element_by_xpath()
  8. find_element_by_css_selector()

#通过id定位:
dr.find_element_by_id("kw")
#通过name定位:
dr.find_element_by_name("wd")
#通过class name定位:
dr.find_element_by_class_name("s_ipt")
#通过tag name定位:
dr.find_element_by_tag_name("input")
#通过xpath定位,xpath定位有N种写法,这里列几个常用写法:
dr.find_element_by_xpath("//*[@id='kw']")
dr.find_element_by_xpath("//*[@name='wd']")
dr.find_element_by_xpath("//input[@class='s_ipt']")
dr.find_element_by_xpath("/html/body/form/span/input")
dr.find_element_by_xpath("//span[@class='soutu-btn']/input")
dr.find_element_by_xpath("//form[@id='form']/span/input")
dr.find_element_by_xpath("//input[@id='kw' and @name='wd']")
#通过css定位,css定位有N种写法,这里列几个常用写法:
dr.find_element_by_css_selector("#kw")
dr.find_element_by_css_selector("[name=wd]")
dr.find_element_by_css_selector(".s_ipt")
dr.find_element_by_css_selector("html > body > form > span > input")
dr.find_element_by_css_selector("span.soutu-btn> input#kw")
dr.find_element_by_css_selector("form#form > span > input")
# 通过link text定位:
dr.find_element_by_link_text("新闻")
dr.find_element_by_link_text("hao123")
# 通过link text定位:
dr.find_element_by_partial_link_text("")
dr.find_element_by_partial_link_text("hao")
dr.find_element_by_partial_link_text("123")

3.1 通过Xpath定位

Xpath语法

https://www.w3school.com.cn/xpath/xpath_syntax.asp

一:从根目录/开始

有点像Linux的文件查看,/代表根目录,一级一级的查找,直接子节点,相当于css_selector中的>号

/html/body/div/p 

二. 根据元素属性选择:

查找具体的元素,必须在前面输入标准开头//,表示从当前节点寻找所有的后代元素

//div/*     div下面的所有的元素

//div//p     先在整个文档里查找div,再在div里查找p节点(只要在内部,不限定是否紧跟) ;等价于 css_selector里的('div p')

//div/p      p是div的直接子节点; 等价于 css_selector里的('div > p')

//*[@style]   查找所有包含style的所有元素,所有的属性要加@;  等价于 css_selector里的('*[style]')

//p[@spec='len']  必须要加引号;等价于 css_selector里的("p[spec='len']")

//p[@id='kw']    xpath中对于id,class与其他元素一视同仁,没有其他的方法

//a[contains(@href,'permalink')]  href属性中包含permalink的a

//input[@type='text' and @name='wd'] 多个属性组合(逻辑运算)

//input[starts-with(@class,'s_ip')]   模糊匹配以xx开头:starts-with

        //*[text()=‘文本内容’]   对于这种文本属性

三. 选择第几个节点

//div/p[2]   选择div下的第二个p节点 ;等价于css_selector里的div>p:nth-of-type(2)  符合p类型的第二个节点

//div/*[2]    选择div下第二个元素

//div/p[position()=2]   position()=2   指定第二个位置;  等价于上面的 //div/p[2] 

          position()>=2      位置大于等于2

          position()<2        位置小于2

          position()!=2    位置不等于2

//div/p[last()]    选择div下的倒数第一个p节点; last()倒数第一个

//div/p[last()-1]    选择div下的倒数第二个p节点;

//div/p[position()=last()]     倒数第一个

//div/p[position()=last()-1]     倒数第二个

//div/p[position()>=last()-2]     倒数第一个,第二个,第三个

四. 组合选择

//p | //button   选择所有的p和button,等价于css_selector里的 p, button

//input[@id='kw' and @class='su']     选择id=kw 并且 class="su"的input元素

五. 兄弟节点的选择

相邻后面的兄弟节点的选择:following-sibling::    两个冒号

//div/following-sibling::p    选择div里相邻的p节点

相邻前面的兄弟节点的选择:preceding-sibling::         此方法在css_selector中没有

//div/preceding-sibling::p[2]   选择div里前面相邻的第二个节点,不加[2]选择的是前面的所有的p节点

六. 选择父节点    

//p[@spec='len']/..    选择p节点的上层节点       此方法在css_selector中没有

//p[@spec='len']/../..   上层节点的上层节点

 七. 在webelement对象里面使用查找Xpath 查找时,必须使用.指明当前节点

food = driver.find_element_by_id('food')

eles = food.find_elements_by_xpath(".//p")    .指明当前节点

eles = food.find_elements_by_xpath("..")   查找当前节点的父节点 

3.2 通过CSS Selector 定位

一:通过ID定位

find_element_by_css_selector("#Email")
find_element_by_css_selector("input#Email")

二:通过Class定位

find_element_by_css_selector(".remember")
find_element_by_css_selector("label.remember")

三:  通过属性定位

find_element_by_css_selector("input")

find_element_by_css_selector("[name='wd']")

find_element_by_css_selector("input[type=’submit’]")

四:  通过位置定位

find_element_by_css_selector("span input")

find_element_by_css_selector("span > input")

find_element_by_css_selector("span + input.s_ipt")

find_element_by_css_selector("ul > li:nth-chlid(2)")

五:  常用CSS Selector

パターン意味

*

任意的元素    

E

Type E 的元素

E[foo]

有"foo" 属性的 E 元素

E[foo="bar"]

"foo" 属性値等于 "bar" 的 E 元素

E[foo^="bar"]

"foo" 属性値 "bar" 开始的 E 元素

E[foo$="bar"]

"foo" 属性値 "bar" 结尾的 E 元素

E[foo*="bar"]

"foo" 属性値含有 "bar" 的 E 元素

E:root

E 元素 (document的根)

E:nth-child(n)

E 元素 (親から n 番目の子)

E:nth-last-child(n)

E 元素 (最後の元素から数えて、親の n 番目の子元素)

E:nth-of-type(n)

E 元素 (同タイプの n 番目の兄弟)

E:nth-last-of-type(n)

E 元素 (最後の元素から数えて、そのタイプの n 番目の兄弟元素)

E:first-child

E 元素 (親の最初の子)

E:last-child

E 元素 (親の最後の子)

E:first-of-type

E 元素 (同タイプの最初の兄弟)

E:last-of-type

E 元素 (同タイプの最後の兄弟)

E F

E 元素の子孫 F 元素

E > F

E 元素の子 F 元素

E + F

E 元素の直後の F 元素

E ~ F

E 元素の後のF 元素

 

4. 控制浏览器操作

 设置浏览器的大小 

  driver.set_window_size(480, 800)

 控制浏览器后退、前进

    driver.back()

    driver.forward()

 刷新页面

    driver.refresh()

from selenium import webdriver

driver = webdriver.Firefox()

#访问百度首页
first_url= 'http://www.baidu.com'
print("now access %s" %(first_url))
driver.get(first_url)

# 参数数字为像素点
print("设置浏览器宽480、高800显示")
driver.set_window_size(480, 800)

#访问新闻页面
second_url='http://news.baidu.com'
print("now access %s" %(second_url))
driver.get(second_url)

#返回(后退)到百度首页
print("back to  %s "%(first_url))
driver.back()

#前进到新闻页
print("forward to  %s"%(second_url))
driver.forward()

driver.refresh() #刷新当前页面

driver.quit()
View Code

5. WebDriver常用方法

 点击和输入

  clear(): 清除文本。

  send_keys (value): 模拟按键输入。

  click(): 单击元素。

 提交

    submit()

 其他常用方法

    size: 返回元素的尺寸。

    text: 获取元素的文本。

    get_attribute(name): 获得属性值。

    is_displayed(): 设置该元素是否用户可见。

from selenium import webdriver

driver = webdriver.Chrome()
driver.get("http://www.baidu.com")

# 获得输入框的尺寸
size = driver.find_element_by_id('kw').size
print(size)

# 返回百度页面底部备案信息
text = driver.find_element_by_id("cp").text
print(text)

# 返回元素的属性值, 可以是 id、 name、 type 或其他任意属性
attribute = driver.find_element_by_id("kw").get_attribute('type')
print(attribute)

# 返回元素的结果是否可见, 返回结果为 True 或 False
result = driver.find_element_by_id("kw").is_displayed()
print(result)

driver.find_element_by_id("kw").clear()
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()

search_text.submit()

driver.quit()
View Code

6. 鼠标事件

   perform(): 执行所有 ActionChains 中存储的行为;

context_click(): 右击;

double_click(): 双击;

drag_and_drop(): 拖动;

move_to_element(): 鼠标悬停。 

from selenium import webdriver
# 引入 ActionChains 类
from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Chrome()
driver.get("https://www.baidu.cn")

# 定位到要悬停的元素
above = driver.find_element_by_link_text("设置")
# 对定位到的元素执行鼠标悬停操作
ActionChains(driver).move_to_element(above).perform()

7. 键盘事件

在使用键盘按键方法前需要先导入 keys 类。

from selenium.webdriver.common.keys import Keys

from selenium import webdriver
# 引入 Keys 模块
from selenium.webdriver.common.keys import Keys

driver = webdriver.Chrome()
driver.get("http://www.baidu.com")

# 输入框输入内容
driver.find_element_by_id("kw").send_keys("seleniumm")

# 删除多输入的一个 m
driver.find_element_by_id("kw").send_keys(Keys.BACK_SPACE)

# 输入空格键+“教程”
driver.find_element_by_id("kw").send_keys(Keys.SPACE)
driver.find_element_by_id("kw").send_keys("教程")

# ctrl+a 全选输入框内容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'a')

# ctrl+x 剪切输入框内容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'x')

# ctrl+v 粘贴内容到输入框
driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'v')

# 通过回车键来代替单击操作
driver.find_element_by_id("su").send_keys(Keys.ENTER)
driver.quit()

  以下为常用的键盘操作:

send_keys(Keys.BACK_SPACE) 删除键(BackSpace)

send_keys(Keys.SPACE) 空格键(Space)

send_keys(Keys.TAB) 制表键(Tab)

send_keys(Keys.ESCAPE) 回退键(Esc)

send_keys(Keys.ENTER) 回车键(Enter)

send_keys(Keys.CONTROL,'a') 全选(Ctrl+A)

send_keys(Keys.CONTROL,'c') 复制(Ctrl+C)

send_keys(Keys.CONTROL,'x') 剪切(Ctrl+X)

send_keys(Keys.CONTROL,'v') 粘贴(Ctrl+V)

send_keys(Keys.F1) 键盘 F1

8. 获取信息

不管是在做功能测试还是自动化测试,最后一步需要拿实际结果与预期进行比较。这个比较的称之为断言。

我们通常可以通过获取title 、URL和text等信息进行断言。

title:用于获得当前页面的标题。

current_url:用户获得当前页面的URL。

text:获取搜索条目的文本信息。

# 打印当前页面title
title = driver.title
print(title)

# 打印当前页面URL
now_url = driver.current_url
print(now_url)

# 获取结果数目
user = driver.find_element_by_class_name('nums').text
print(user)

9. 设置元素等待

WebDriver提供了两种类型的等待:显式等待和隐式等待。

显式等待

显式等待使WebdDriver等待某个条件成立时继续执行,否则在达到最大时长时抛出超时异常(TimeoutException)。

WebDriverWait类是由WebDirver 提供的等待方法。.

在设置时间内,默认每隔一段时间检测一次当前页面元素是否存在,如果超过设置时间检测不到则抛出异常

WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)

 ◆ driver :浏览器驱动。

 ◆ timeout :最长超时时间,默认以秒为单位。

 ◆ poll_frequency :检测的间隔(步长)时间,默认为0.5S。

 ◆ ignored_exceptions :超时后的异常信息,默认情况下抛NoSuchElementException异常。

    WebDriverWait()一般由until()或until_not()方法配合使用,下面是until()和until_not()方法的说明。

 ◆ until(method, message=‘’)
调用该方法提供的驱动程序作为一个参数,直到返回值为True。

until_not(method, message=‘’)
调用该方法提供的驱动程序作为一个参数,直到返回值为False。

在本例中,通过as关键字将expected_conditions 重命名为EC,并调用presence_of_element_located()方法判断元素是否存在。

隐式等待

 implicitly_wait() 默认参数的单位为秒

from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from time import ctime

driver = webdriver.Firefox()

# 设置隐式等待为10秒
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")

try:
    print(ctime())
    driver.find_element_by_id("kw22").send_keys('selenium')
except NoSuchElementException as e:
    print(e)
finally:
    print(ctime())
    driver.quit()

本例中设置等待时长为10秒。首先这10秒并非一个固定的等待时间,它并不影响脚本的执行速度。

它并不针对页面上的某一元素进行等待。当脚本执行到某个元素定位时,如果元素可以定位,则继续执行;

如果元素定位不到,则它将以轮询的方式不断地判断元素是否被定位到。

假设在第6秒定位到了元素则继续执行,若直到超出设置时长(10秒)还没有定位到元素,则抛出异常。

10. 定位一组元素

  • find_elements_by_id()
  • find_elements_by_name()
  • find_elements_by_class_name()
  • find_elements_by_tag_name()
  • find_elements_by_link_text()
  • find_elements_by_partial_link_text()
  • find_elements_by_xpath()
  • find_elements_by_css_selector()

11. 多表单切换

driver.switch_to.frame('frameId')

driver.switch_to.parent_frame()

driver.switch_to.default_content()

driver = webdriver.Chrome()
driver.get("http://www.126.com")

driver.switch_to.frame('x-URS-iframe')
driver.find_element_by_name("email").clear()
driver.find_element_by_name("email").send_keys("username")

当ID是随机内容,不可用的时候,直接定位frame(0) 即第一个frame

driver.switch_to.frame(0) 

12. 多窗口切换

 current_window_handle:获得当前窗口句柄。 

window_handles:返回所有窗口的句柄到当前会话。 

switch_to.window(handle):用于切换到相应的窗口,用于不同表单之间的切换。 

from selenium import webdriver
import time

driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")

# 获得百度搜索窗口句柄
sreach_windows = driver.current_window_handle

driver.find_element_by_link_text('登录').click()
driver.find_element_by_link_text("立即注册").click()

# 获得当前所有打开的窗口的句柄
all_handles = driver.window_handles

# 进入注册窗口
for handle in all_handles:
    if handle != sreach_windows:
        driver.switch_to.window(handle)
        print('now register window!')
        driver.find_element_by_name("account").send_keys('username')
        driver.find_element_by_name('password').send_keys('password')
        time.sleep(2)
        # ……

driver.quit()

13. 警告框处理

switch_to_alert() : 接受这个弹窗。  

text:返回 alert/confirm/prompt 中的文字信息。 

accept():接受现有警告框。 

dismiss():解散现有警告框。 

send_keys(keysToSend):发送文本至警告框。keysToSend:将文本发送至警告框。 

# 接受警告框
driver.switch_to.alert.accept()

14. 下拉框选择

from selenium.webdriver.support.select import Select

Select类用于定位select标签。

select_by_value() 方法用于定位下接选项中的value值。

# 搜索结果显示条数
sel = driver.find_element_by_xpath("//select[@id='nr']")
Select(sel).select_by_value('50')  # 显示50条

15. 文件上传

对于通过input标签实现的上传功能,可以将其看作是一个输入框,即通过send_keys()指定本地文件路径的方式实现文件上传。

# 定位上传按钮,添加本地文件
driver.find_element_by_name("file").send_keys('D:\upload_file.txt')

16. cookie操作

WebDriver操作cookie的方法:

get_cookies(): 获得所有cookie信息。

get_cookie(name): 返回字典的key为“name”的cookie信息。 

add_cookie(cookie_dict) : 添加cookie。“cookie_dict”指字典对象,必须有name 和value 值。 

delete_cookie(name,optionsString):删除cookie信息。“name”是要删除的cookie的名称,“optionsString”是该cookie的选项,目前支持的选项包括“路径”,“域”。 

delete_all_cookies(): 删除所有cookie信息。 

from selenium import webdriver

driver = webdriver.Firefox()
driver.get("http://www.youdao.com")

# 向cookie的name 和value中添加会话信息
driver.add_cookie({'name': 'key-aaaaaaa', 'value': 'value-bbbbbb'})

# 遍历cookies中的name 和value信息并打印,当然还有上面添加的信息
for cookie in driver.get_cookies():
    print("%s -> %s" % (cookie['name'], cookie['value']))

driver.quit()

17. 调用JavaScript代码

    driver.execute_script()

# 通过javascript设置浏览器窗口的滚动条位置
js="window.scrollTo(100,450);"
driver.execute_script(js)
sleep(3)
这样可以实现滚动到指定元素
element.location_once_scrolled_into_view

18. 调用JavaScript代码窗口截图

# 截取当前窗口,并指定截图图片的保存位置
driver.get_screenshot_as_file("D:\baidu_img.jpg")

19. 关闭浏览器

close() 关闭单个窗口 

quit() 关闭所有窗口 

————————————————————————————————————————————————————————————————
参考链接:

1. https://blog.csdn.net/u012941152/java/article/details/83011110  作者 雪国的花儿

2. https://blog.csdn.net/zbj18314469395/article/details/99652088   作者 

3. http://www.testclass.net/selenium_python  主要参考 作者 虫师

 

原文地址:https://www.cnblogs.com/changxinblog/p/13168823.html