系统本身带有 python 2.7
替换了系统的 Python 2.7 之后悲剧了,Xcode 打不开
代码前加 #coding=utf-8 统一编码成 UTF-8,注空格两边不需要加空格
IDLE 快捷键
快捷键 |
说明 |
TAB |
自动补全 |
CTRL+P |
回退到上一次编辑的代码 |
CTRL+N |
前进到下一次编辑的代码 |
CTRL+ENTER |
运行代码,默认 enter 运行代码,但是如果语法未完成 enter 为换行,需要 ctrl+enter 运行代码 |
查找元素
表达式 |
结果 |
说明 |
find_element_by_id |
查找对应 id 的元素 |
|
find_element_by_name |
查找对应名称的元素 |
|
find_element_by_xpath |
查找对应 xpath 的元素 |
|
find_element_by_link_text |
查找对应超链接文本的元素 |
|
find_element_by_partial_link_text |
查找含有超链接文本的元素 |
|
find_element_by_tag_name |
查找对应标签名的元素 |
|
find_element_by_class_name |
查找对应类名的元素 |
|
find_element_by_css_selector |
查找对应 css 选择器的元素 |
|
查找多个相同元素(返回 list 列表)
表达式 |
结果 |
说明 |
find_elements_by_name |
|
|
find_elements_by_xpath |
|
|
find_elements_by_link_text |
|
|
find_elements_by_partial_link_text |
|
|
find_elements_by_tag_name |
|
|
find_elements_by_class_name |
|
|
find_elements_by_css_selector |
|
|
list 调用表达式 |
结果 |
说明 |
len() |
计算元素的个数 |
|
pop() |
获取列表中的某个元素 |
|
pop() 或 pop(-1) |
默认获取一组元素中的最后一个 |
|
pop(0) |
默认获取一组元素中的第一个 |
|
浏览器操作
表达式 |
结果 |
说明 |
b = webdriver.Chrome() |
获取 webdriver |
|
b.get_attribute |
获取属性名 |
|
b.id |
获取类型 |
|
b.close |
关闭当前窗口 |
|
b.quit |
关闭所有窗口,退出相关的驱动程序 |
|
b.get('http://www.baidu.com') |
打开指定网址 |
|
b.get(r'/Desktop/test.html') |
打开本地html |
|
b.title |
网页标题 |
|
b.current_url |
网页url |
|
b.maximize_window() |
窗口最大化 |
|
b.set_window_size() |
设置窗口大小 |
b.set_windo_size(480 * 800) |
b.back() |
后退 |
|
b.forward() |
前进 |
|
b.refresh() |
刷新 |
|
b.get_screenshot_as_file(path) |
窗口截取 |
|
元素操作
表达式 |
结果 |
说明 |
e.get_attribute |
获取属性名 |
|
e.id |
获取类型 |
|
e.clear |
清除输入值 |
|
e.send_keys() |
输入值 |
|
e.size |
返回元素的尺寸 |
|
e.text |
获取元素的文本 |
|
e.get_attribute(name) |
获得属性值 |
|
e.is_displayed() |
设置该元素是否用户可见 |
|
函数
XPath 和 CSS 通过 Chrome 插件容易处理
Chrome 插件:XPathHelper
XPath 通过路径选取节点
表达式 |
结果 |
说明 |
/xxx |
选取根节点 |
|
/xxx/yyy |
根据绝对路径选择元素 |
|
//xxx |
整个文档扫描,找到所有xxx元素 |
默认获取第一个,可以用下标去获取 |
//xxx/yyy |
所有元素为xxx的yyy元素 |
|
. |
选取当前节点的父元素节点 |
|
.. |
选取父元素地址 |
|
//xxx[@id] |
选取所有xxx元素中有id属性的元素 |
//input[not(@id)] |
//xxx[@id=yyy] |
选取所有xxx元素id属性为yyy的元素 |
|
eg: b.find_element_by_xpath('//*[count(input)=2]')
层级与属性的结合
eg: b.find_element_by_xpath("//form[@id='form']/span/input")
使用逻辑运算符
eg: b.find_element_by_xpath("//input[@id='kw' and @class='su']/span/input")
XPath 路径表达式选取节点设置
表达式 |
结果 |
说明 |
//*[count(xxx)=2] |
统计xxx元素个数=2的节点 |
|
//*[local-name()='xxx'] |
找到tag为xxx的元素 |
|
//*[starts-with(local-name), 'x'] |
找到所有tag以x开头的元素 |
|
//*[contains(local-name(), 'x')] |
找到所有tag包含x的元素 |
|
//*[string-length(local-name()) = 3] |
找到所有tag长度为3的元素 |
|
//xxx |
//yyy |
多个路径查找 |
CSS 选择器的常见语法
选择器 |
例子 |
描述 |
.class |
.intro |
class选择器,选择class="intro"的所有元素 |
#id |
#classname |
id选择器,选择id="firstname"的所有元素 |
* |
* |
选择所有元素 |
element |
p |
元素所有<p>元素 |
element > element |
div > input |
选择父元素为 <div> 的所有 input 元素 |
element + element |
div + input |
选择同一级中紧接在 <div> 元素之后的所有 <input> 元素 |
[attribute=value] |
[target=_blank] |
选择 target="_blank" 的所有元素 |
组合定位 |
span.bg s_ipt_wr>input.s_ipt |
|
鼠标事件
from selenium.webdriver.common.action_chains import
eg: ActionChains(driver).move_to_element(ele)
模拟鼠标的操作
- perform 执行所有 ActionChains 中存储的行为
- ActionChains(driver) 模拟用户行为
表达式 |
结果 |
说明 |
context_click |
右击事件 |
|
double_click |
双击事件 |
|
drag_and_drop |
拖动 |
drag_and_drop(element, targetElement) |
move_to_element() |
鼠标停在一个元素上 |
|
click_and_hold |
按下鼠标左键在一个元素上 |
|
用 By 定位元素
- from selenium.webdriver.common.by import By
表达式 |
说明 |
find_element(By.ID, "kw") |
|
find_element(By.NAME, "wd") |
|
find_element(By.CLASS_NAME, "s_ipt") |
|
find_element(By.TAG_NAME, "input") |
|
find_element(By.LINK_TEXT, "新闻") |
|
find_element(By.PARTIAL_LINK_TEXT, "新") |
|
find_element(By.XPATH, "//*[@class='bg s_btn']") |
|
find_element(By.CSS_SELECTOR, "span.bg s_btn_wr>input#su") |
|
键盘事件
- from selenium.webdriver.common.keys import keys
表达式 |
结果 |
说明 |
send_keys(Keys.BACK_SPACE) |
退格键 |
|
send_keys(Kyes.SPACE) |
空格键 |
|
send_keys(Keys.CONTRL, 'a') |
全选 |
|
send_keys(Keys.CONTRL, 'v') |
粘贴 |
|
send_keys(Keys.CONTRL, 'c') |
复制 |
|
send_keys(Keys.CONTRL, 'x') |
剪切 |
|
send_keys(Keys.ENTER) |
回车 |
|
send_keys(Keys.F1) |
F1 |
|
定义变量 : account = ‘admin’
函数 : def login_test():
try:
e_error = d.find_element_by_link_text(‘该账号格式不正确’)
print('Account Error')
except:
print('Account And Pwd Right!')
selenium 的等待方法
表达式 |
结果 |
说明 |
implicitly_wait() |
设置webdriver等待时间(控件搜索时间) |
|
WebDriverWait |
等待条件满足或者超时后退出 |
|
from selenium.webdriver.support.ui import WebDriverWait |
WebDriverWait(driver, times).until(func) |
|
from selenium.webdriver.support.ui import By # By
from selenium.webdriver.support import expected_conditions as EC # EC
将 expected_conditions as 为 EC
WebDriverWait
WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
driver: 浏览器驱动
timeout: 最长超时时间,默认以秒为单位
poll_frequency: 检测的间隔(步长)时间,默认为 0.5 S
ignored_exceptions: 超时后的异常信息,默认情况下抛出 NoSuchElementException 异常
# 一般配合 until() 或 until_not() 方法配合使用
until(method, message='')
# 调用该方法提供的驱动程序作为参数,直到返回 True
until_not(method, message='')
# 调用该方法提供的驱动程序作为一个参数,直到返回为 False
presence_of_element_located() 方法判断元素是否存在
表达式 |
说明 |
title_is |
判断当前页面的标题是否等于预期 |
title_contains |
判断当前页面的标题是否包含预期字符串 |
presence_of_element_located |
判断元素是否被加在 DOM 树里,并不代表该元素一定可见 |
visibility_of_element_located |
判断元素是否可见(可见代表元素非隐藏,并且元素的宽和高都不等于0) |
visibility_of |
与上一个方法作用相同,只是上一个方法参数为定位,该方法接受的参数为定位后的元素 |
presence_of_all_elements_located |
判断是否至少有一个元素存在于 DOM 树中。例如,在个页面中有 n 个元素的 class 为 "wp",那么只要有一个存在就返回 "true" |
text_to_be_present_in_element |
判断某个元素中的text是否包含了预期的字符串 |
text_to_be_present_in_element_value |
判断某个元素的 value 属性是否包含了预期的字符串 |
frame_to_be_available_and_switch_to_it |
判断该表单是否可以切换进去,如果可以,返回 True 并且 switch 进去,否则返回 False |
invisibility_of_element_located |
判断某个元素是否不存在 DOM 树或不可见 |
element_to_be_clickable |
判断元素是否可见并且是可以点击的 |
staleness_of |
等到一个元素从 DOM 树中移除 |
element_to_be_selected |
判断某个元素的选中状态是否被选中,一般用在下拉列表 |
element_selection_state_to_be |
判断某个元素的选中状态是否符合预期 |
element_located_selection_state_to_be |
与上一个方法作用相同,只是上一个方法参数为定位后的元素,该方法接收的参数为定位 |
alert_is_present |
判断页面上是否存在 alert |
隐式等待
通过一定的时长等待页面上某个元素加载完成,如果超出设置时长还没有被加载出来,则抛出异常
implicitly_wait()
sleep 休眠方法
time.sleep(2)
多表单切换
frame/iframe 表单嵌套页面的应用
switch_to.frame() 遇到 frame/iframe 表单嵌套页面的应用,需要先切换的表单,再定位百度输入框
switch_to.parent_content() 跳出当前一级表单
switch_to.default_content() 跳回最外层的页面
切换窗口
b.window_handles
b.current_window_handle
b.switch_to_window(d.window_handles[2])
获取当前路径下的文件
file_path = 'file:///' + os.path.abspath('checkbox.html')
alert 对话框处理
表达式 |
说明 |
b.switch_to_alert() |
切换到对话框 |
alter.text |
alert/confirm/prompt 中的文字信息 |
alter.accept() |
接受现有警告框 |
alter.dismiss() |
关闭现有警告框 |
send_keys(keysToSend) |
发送文本至警告框 |
上传文件
web 上传的两种方式:
- 普通上传:将文本文件的路径作为一个值放在 input 标签中,通过 form 表单将这个值提交给服务器
- 插件上传:一般是基于 Flash、JavaScript 或 Ajax 等技术所实现的上传功能
# 定位上传按钮,添加本地文件
driver.find_element_by_name("file").send_keys('D:\\upload_file.txt')
下载文件
操作 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 信息 |
调用 JavaScript
window.scrollTop()
window.scrollTo(左边距,上边距)
# 模拟滚动条
js = "window.scrollTo(100, 450)"
driver.execute_script(js)
处理 HTML 的视频播放
from time import sleep
driver = webdriver.Chorme()
driver.get("http://videojs.com/")
video = driver.find_element_by_xpath("body/Setion[1]/div/video")
# 返回播放文件地址
url = driver.execute_script("return arguments[0].currentSrc;", video)
print(url)
# 播放视频
print("start")
driver.execute_script("return arguments[0].play()", video)
# 播放 15 分钟
sleep(15)
# 暂停视频
print("stop")
driver.execute_script("arguments[0].pause()", video)
driver.quit()
表达式 |
说明 |
arguments |
argument 对象包含了函数调用的参数数组,[0] 表示取对象的第 1 个值 |
currentSrc |
熟悉返回当前音频/视频的 URL。如果未设置音频/视频,则返回空字符串 |
load() |
视频加载 |
play() |
视频播放 |
pause() |
视频暂停 |
关于验证码的处理
- 去掉验证码,但是会给正式环境测试带来一定的风险
- 设置万能验证码
- 验证码识别技术,Python-tesseract 来识别图片验证码,能够读取任何常规的图片文件(JPG/GIF/PNG/TIFF等等)
- 记录 cookie,添加登录后的 cookie 完成登录操作
logging 模块
- 提供一个标准的信息输出接口
- basicConfig() 方法用于基本信息的定义,只能捕捉客户端向服务器发送的POST请求,但是无法获取服务器所返回的应答信息
总结
- 精通前端技术会有助于自动化编写
- 开发在代码设计中是否考虑容易自动化