前言
看完这篇文章你可以收获神马?你可以让计算机自动地去完成你想要做的一系列事情,比如:去浏览器中搜索一些你想要了解的知识,获取去网上找一个你想听的歌,没错,不用你来操作,它可以自己完成。
目录
【1】一个简单的自动化脚本
【2】元素的定位
【1】id定位
【2】tag name和class name定位
【3】link text和partial link text定位
【4】css selector定位
【5】XPath定位
【3】操作测试对象
【4】添加等待
(1)sleep等待
(2)隐式等待(智能等待)
【5】信息打印
【6】 对浏览器的操作
【7】键盘事件
【1】键盘按键
【2】键盘组合键
【8】鼠标事件
【9】复杂元素定位
(1)定位一组元素
(2) 多层框架定位
(3)层级定位
(4)下拉框定位
【10】 特殊情况的处理
(1)alert弹框的处理
(2)div块的处理
(3)上传文件
打开谷歌浏览器,进入到百度搜索页面搜索关键字“南山南”,最后退出浏览器。
# coding = utf-8
from selenium import webdriver
import time
browser = webdriver.Chrome()
time.sleep(3)
browser.get("http://www.baidu.com")
time.sleep(3)
browser.find_element_by_id("kw").send_keys("南山南")
time.sleep(3)
browser.find_element_by_id("su").click()
browser.quit()
脚本解析:
- coding=utf-8:设置编码格式,防止乱码,编辑器默认utf-8,可以不用设置;
- from selenium import webdriver:导入webdriver工具包,这样就可以使用相关的API;
- browser=webdriver.Chrome():获取被控制的浏览器的驱动,这里获取Chrome浏览器,也可以获取其他浏览器,必须安装相应的浏览器驱动;
- browser.find_element_by_id("kw").send_keys("南山南"):通过元素的id定位想要操作的元素,并向其输入相应的文本内容;
- browser.find_element_by_id("su").click():通过id定位到元素,并进行点击操作;
- browser.quit():退出并关闭窗口。
quit()和close()的区别:
- colse()仅仅是关闭当前浏览器的窗口;
- quit()方法不仅关闭窗口,还会彻底的退出webdriver,释放与driverserver之间的连接。
对象的定位是自动化测试的核心,想要操作一个对象,首先需要识别这个对象,我们可以通过id等属性找到元素,必须保证页面上该属性的唯一性。常用的对象定位方法有以下几种:
- id
- name
- classname
- link text
- partial link text
- tag name
- xpath
- css selector
id是页面元素的属性,,是最常用的元素定位的方法,但不是所有元素都有id。一般可以使用id来唯一的定位这个元素。
如,通过Chrome浏览器的F12,可以找到百度输入框的属性信息:
从上面的属性信息中,可以看到,不单单只有id和name属性,还由class和tagname(标签名):
- input标签可以通过find_element_by_tag_name("input") 函数来定位;;
- class="s_ipt"可以通过find_element_by_class_name("s_ipt")函数定位百度输入框。。
需要注意,不是所有的元素都可以使用这两种方式进行定位,必须要保证该元素的这两种属性在页面上是唯一的。
- link text:定位一个文字链接,可以通过链接的内容来定位,当然链接的内容在当前页面必须唯一;
- partial link text:通过部分连接定位,可以只通过链接的一部分文字进行匹配。
可以通过css中的选择器对页面的元素进行定位。
通过cee的id选择器来定位元素:
browser.find_element_by_css_selector("#kw").send_keys("薛之谦")
browser.find_element_by_css_selector("#su").click()
可以对页面中的任意元素进行定位。
获取元素的XPath:
首先右键元素进入到检查页面
定位到元素之后,需要对定位的元素进行操作。webdriver中常见的操作对象的方法:
- click:点击对象;
- send_keys:在对象上模拟按键输入
- clear:清楚对象输入的文本内容;
- submit:提交表单;
- text:用于获取元素的文本信息。
引人入time包,调用sleep方法使其固定的休眠的一段时间。
from selenium import webdriver
import time
browser = webdriver.Chrome()
browser.get("http://www.baidu.com")
time.sleep(2)
browser.find_element_by_css_selector("#kw").send_keys("薛之谦")
browser.find_element_by_css_selector("#su").click()
#搜索薛之谦,等待5秒钟后点击百度百科
time.sleep(5)
browser.find_element_by_link_text("百度百科").click()
time.sleep(5)
browser.quit()
【需要注意】
上面的代码,如果去掉这个固定的休眠时间,就会如下的错误:
未找到链接文字“百度百科”,因为在点击之后搜索的页面还没有被加载出来,无法对元素进行定位。
我们发现,如果设置sleep进行等待,可能会消耗大量的时间,所以可以添加implicitly_wait(time) 方法就可以方便的实现智能等待。选择一个时间范围内智能等待。
【工作原理】
隐式等待并非一个固定的等待时间。当脚本执行到某个元素的定位时,如果元素可以定位,则继续执行;如果元素定位不到,则以轮询的方式不断地判断元素是否被定位到,直到超出设置的时长。
打印页面的title和url:
from selenium import webdriver
import time
browser = webdriver.Chrome()
browser.get("http://www.baidu.com")
title=browser.title
print(title)
url=browser.current_url
print(url)
- 浏览器最大化:调用启动的浏览器不是全屏的,有时候会影响我们观看脚本运行,使用maximize_window()方法对窗口进行最大化;
- 设置浏览器的宽高:set_window_size(width,high)
- 操作浏览器的前进后退:
【1】前进:forward()
【2】后退:back()- 控制浏览器滚动条:浏览器的滚动条的控制需要哦依靠js脚本
【1】将浏览器滚动条滑到最顶端:【2】将浏览器滚动条滑动到最底端:# 距顶端的距离设置为零 driver.documentElement.scrollTop=0
js="var q=document.documentElement.scrollTop=10000" # excute_script()在当前窗口/框架同步执行js driver.excute_script(js)
所有的键盘操作,必须建立到定位到元素的基础上(基于元素操作)。使用键盘按键,需要引入keys包:
from selenium.webdriver.common.keys import Keys
通过send_keys()方法调用按键:
send_keys(Keys.TAB) # TAB
send_keys(Keys.ENTER) # 回车
send_keys(Keys.SPACE) #空格键
send_keys(Keys.ESCAPE) #回退键(Esc)
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)
需要导入工具包ActionChains:
from selenium.webdriver.common.action_chains import ActionChains
ActionChains类
方法名 | 说明 |
context_click() | 鼠标右击 |
double_ click() | 双击 |
drag_and_drop() | 拖动 |
move_to_element() | 移动 |
webdriver可以很方便的使用findElement方法来定位某个特定的对象,不过有时候我们需要定位一组对象,需要使用findElements方法:
- 批量操作对象,将页面上所有的checkbox都勾上
- 先获取一组元素,再在这组对象中过滤出需要具体定位的一些对象。
例:勾选页面上所有的checkbox
from selenium import webdriver
import time
import os
driver=webdriver.Chrome()
# html文件所在路径
path='file:///'+os.path.abspath('C:\\Users\\Lenovo\\Desktop\\selenium2html\\checkbox.html')
driver.get(path)
# 选择页面上所有的input。然后过滤出checkbox并勾选
checkboxs=driver.find_elements_by_tag_name('input')
for checkbox in checkboxs:
if checkbox.get_attribute('type')=='checkbox':
checkbox.click()
time.sleep(5)
driver.quit()
解决不同层框架上的页面的元素的定位:
- 如果要定位一个层级框架中的元素,必须先跳到这个框架层级,才可以进行定位;
- 如果要定位某一个层级,必须从默认的页面跳转。
- 定位到一个层级:switch_to.frame(id)通过frame的id等属性来定位框架,将当前定位的主体切换到frame里;
- switch_to.default_content():从frame中嵌入的页面里跳出,跳回到最外面的默认页面。
有时候我们需要定位的元素没有在页面直接展示,需要对页面元素进行一系列操作之后才展示出来,这时候我们需要一层层去定位。(通过鼠标事件进行操作)
例:打开本地html,点击link1后定位到其中一个栏使其高亮显示。
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
import os
driver = webdriver.Chrome()
path = 'file:///'+os.path.abspath('C:\\Users\\Lenovo\\Desktop\\selenium2html\\level_locate.html')
driver.get(path)
# 定位到link1,点击
driver.find_element_by_link_text('Link1').click()
driver.implicitly_wait(5)
# 定位Something else here
element = driver.find_element_by_link_text('Something else here')
# 鼠标移动到Something else here ,高亮显示
ActionChains(driver).move_to_element(element).perform()
time.sleep(4)
driver.quit()
对于一般的元素,我们只需要一次就定位,但下拉框的内容需要进行两次定位,先定位到下拉框对下拉框进行操作后,在定位到下拉框中的选项:
- 直接使用xpath来定位
- 先定位出一组元素,然后根据元素的属性进行过滤筛选,再进行具体操作;
- 先定位出一组元素,再通过数组下标的方式定位
例:选中下拉框中的一个指定选项。
driver=webdriver.Chrome()
path='file:///'+os.path.abspath('C:\\Users\\Lenovo\\Desktop\\selenium2html\\drop_down.html')
driver.get(path)
time.sleep(2)
# 定位到下拉框
driver.find_element_by_id('ShippingMethod').click()
time.sleep(2)
# 根据下拉框的选项定位到value值等于8.34的选项
elements=driver.find_elements_by_tag_name('option')
for element in elements:
if element.get_attribute('value')=='8.34':
element.click()
time.sleep(4)
driver.quit()
- 定位弹出框/获取弹出框的操作句柄:switch_to.alert;
- 关闭弹框:accept();
- alert弹框中输入信息:send_keys()
例:定位到点击按钮,跳出弹框,在弹框中输入内容,关闭弹框
from selenium import webdriver
import time
import os
driver=webdriver.Chrome()
path='file:///'+os.path.abspath('C:\\Users\\Lenovo\\Desktop\\selenium2html\\send.html')
driver.get(path)
# 定位元素,点击,出现弹出框
driver.find_element_by_tag_name("input").click()
time.sleep(4)
# 定位弹出框
alert=driver.switch_to.alert
# 弹出框中输入信息
alert.send_keys("大秃噜")
time.sleep(2)
# 关闭弹框
alert.accept()
time.sleep(5)
driver.quit()
如果页面的元素比较多,利用元素的属性无法请确的定位到这个元素的时候,我们可以先定位这个元素所在的div块,再去定位这个元素。
- 首先定位到div模块;
- 再去精确寻找需要定位的元素。
上传文件一般要打开一个本地窗口,从窗口选择本地文件添加。我们需要考虑如何添加上传文件:定位到上传按钮,通过send_keys添加本地文件路径就行。(绝对路径和相对路径都可以)
为什么有些第三方网站的页面元素无法进行定位?
为了安全性考虑,防止有些人使用自动化脚本来破解密码。每次打开网页网页中元素的id属性会不一样,无法使用自动化脚本进行操作。