环境搭建
安装python
python的安装文件下载地址, 这里使用的是Python 3.6.4
建议创建一个python的主目录方便python管理
[图片上传失败...(image-78992d-1515987136052)]
完成后将%python_home%\;%python_home%\Scripts
加入path中
[图片上传失败...(image-f92bf6-1515987136052)]
这里教大家一个技巧 如果设置了某个变量但是发现它的value没有变化 那么我们仅仅需要在cmd中修改下它 比如path=1 然后退出重进即可
另外为了方便python模块管理, 建议安装pip, 具体请参见install pip
使用pip安装selenium pip install selenium
安装浏览器驱动
驱动列表下载
Firefox浏览器驱动 geckodriver
Chrome浏览器驱动 chromedriver taobao备用地址
其他drivers 在这里下载selenium-Drivers 下载完成后将其加入path中
这边是windows10以及使用chrome进行开发测试。
测试功能是否可用
from selenium import webdriver
driver = webdriver.Chrome();
driver.get('http://www.baidu.com'); # 一定是http://xxx 需要协议
search_word = driver.find_element_by_id("kw");
search_word.clear();
search_word.send_keys('selenium');
search_word.click();
selenium
本地文件测试
处于前期一些测试,我们不能直接在别人网站上直接进行测试&练习;所以需要下载到本地为html文件,然后进行测试
# 这个html与py文件放在一个目录下,所以使用了os.path.abspath
localhtml = 'file:///' + os.path.abspath('local.html')
driver.get(localhtml)
定位方法
Selenium提供了8种定位方式。
id -> find_element_by_id()
name -> find_element_by_name()
class name -> find_element_by_class_name()
tag name -> find_element_by_tag_name()
link text -> find_element_by_link_text()
partial link text -> find_element_by_partial_link_text()
xpath -> find_element_by_xpath()
css selector -> find_element_by_css_selector()
个人推荐使用xpath W3school教程
控制浏览器
from selenium import webdriver
import time
home_page = "http://m.baidu.com";
secondary_page = "http://news.baidu.com"
driver = webdriver.Chrome();
driver.get(home_page);
# 设置浏览器窗口 px 480 * 800
driver.set_window_size(480, 800);
# 控制浏览器后退 前进
driver.get(secondary_page);
time.sleep(1);
driver.back(); # 后退
time.sleep(1);
driver.forward(); # 前进
# 刷新页面
driver.refresh();
webDriver常用方法
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
home_page = "http://m.baidu.com";
driver = webdriver.Chrome();
driver.get(home_page);
# 设置浏览器窗口 px 480 * 800
driver.set_window_size(480, 800);
#------------- 单纯对元素进行操作
# 清空百度搜索栏的输入信息
driver.find_element_by_id("index-kw").clear();
time.sleep(0.5)
# 在百度搜索栏中填入 selenium
driver.find_element_by_id("index-kw").send_keys("selenium1");
# 点击"百度一下按钮"按钮
driver.find_element_by_id("index-bn").click();
#------------- 元素 + submit
# 在百度搜索栏中填入 selenium
search_field = driver.find_element_by_id("kw");
# 清空百度搜索栏的输入信息
search_field.clear(); # 不知道为什么不起作用 所以使用下面的方式 发送Backspace键
search_word_count = 0
while search_word_count < len(search_field.text) :
time.sleep(0.3)
search_word_count += 1
search_field.send_keys(Keys.BACK_SPACE)
search_field.send_keys("selenium2");
print('输入框大小', search_field.size, '输入框文本', search_field.text, '对用户是否可见', search_field.is_displayed());
# 提交表单 相当于按了一个enter
search_field.submit();
鼠标事件
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
home_page = "http://www.baidu.com";
driver = webdriver.Chrome();
driver.get(home_page);
# 设置浏览器窗口 px 480 * 800
logon = driver.find_element_by_link_text("设置");
# move_to_element 移动到某个节点
# drag_and_drop 拖动
# double_click 双击
# context_click 右击
# perform 执行所有存储在Action chains的操作 所以在最后必须有它 否则所有操作无法执行
ActionChains(driver).move_to_element(logon). \
context_click(). \
perform() ;
获取搜索结果
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from time import sleep
home_page = "http://www.baidu.com";
driver = webdriver.Chrome();
driver.get(home_page);
# 打印当前页面
print('Before search------------------')
print(driver.title) # 打印标题
print(driver.current_url) # 打印url
driver.find_element_by_id("kw").send_keys("selenium");
driver.find_element_by_id("su").click();
sleep(1)
print('After search------------------')
print(driver.title) # 打印标题
print(driver.current_url) # 打印url
search_count = driver.find_element_by_class_name("nums").text # 打印输出结果
print(search_count)
元素等待
- 显式等待
显式等待是WebdDriver等待某个条件成立时继续执行,否则在达到最大时长时抛出超时异常(TimeoutException)。
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。
- 隐式等待
implicitly_wait()默认参数的单位为秒,本例中设置等待时长为10秒。首先这10秒并非一个固定的等待时间,它并不影响脚本的执行速度。其次,它并不针对页面上的某一元素进行等待。当脚本执行到某个元素定位时,如果元素可以定位,则继续执行;如果元素定位不到,则它将以轮询的方式不断地判断元素是否被定位到。假设在第6秒定位到了元素则继续执行,若直到超出设置时长(10秒)还没有定位到元素,则抛出异常。
import time
from selenium.common import exceptions
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as Exception
driver = webdriver.Chrome()
driver.get('http://www.baidu.com')
# 1.隐式等待 查找元素
'''
element = WebDriverWait(driver, 2, 0.5,).until(
method = Exception.presence_of_element_located((By.ID, "kw")),
message= "not found the node 'kw'"
);
element.send_keys('python');
'''
# 2.隐身等待 查找元素
driver.implicitly_wait(2);
try:
print(time.ctime());
driver.find_element_by_id("kw").send_keys('python');
driver.find_element_by_id("su").click();
except exceptions.NoSuchElementException as e:
print(e)
finally:
print(time.ctime());
#driver.quit();
定位一组元素
这里比抓取一个的method多了一个s,其他用法都差不多
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()
[图片上传失败...(image-fdfd06-1515987136052)]
from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
sleep(1)
# 定位一组元素
texts = driver.find_elements_by_xpath('//div/h3/a')
# 循环遍历出每一条搜索结果的标题
for t in texts:
print(t.text)
多表单切换(模拟登录)
在Web应用中经常会遇到frame/iframe表单嵌套页面的应用,WebDriver只能在一个页面上对元素识别与定位,对于frame/iframe表单内嵌页面上的元素无法直接定位。这时就需要通过switch_to.frame()方法将当前定位的主体切换为frame/iframe表单的内嵌页面中。
[图片上传失败...(image-e1b034-1515987136052)]
from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
driver.get("http://mail.163.com");
sleep(1); # 需要等待等html加载完成 否则会报frame没有找到
driver.switch_to.frame('x-URS-iframe')
email = driver.find_element_by_name("email");
email.clear();
email.send_keys('username');
sleep(1)
passwd = driver.find_element_by_name("password");
passwd.clear();
passwd.send_keys("password");
sleep(1)
driver.find_element_by_id("dologin").click();
多窗口切换
在页面操作过程中有时候点击某个链接会弹出新的窗口,这时就需要主机切换到新打开的窗口上进行操作。WebDriver提供了switch_to.window()方法,可以实现在不同的窗口之间切换。
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
driver = webdriver.Chrome();
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")
driver.find_element_by_link_text('登录').click()
driver.find_element_by_link_text("立即注册").click()
# 获得当前窗口句柄
logon_window = driver.current_window_handle
# 获得当前所有打开的窗口的句柄
all_handles = driver.window_handles
# 进入注册窗口
for handle in all_handles:
if handle != logon_window: # 因为就两个窗口 不是当前窗口 就是新打开的窗口 我们就切换过去
driver.switch_to.window(handle)
driver.find_element_by_name("userName").send_keys('Elan我爱大头人')
time.sleep(1)
driver.find_element_by_name('phone').send_keys('16612634667')
time.sleep(1)
driver.find_element_by_id('TANGRAM__PSP_3__password').send_keys('Pass@1234')
time.sleep(1)
driver.find_element_by_name('verifyCode').send_keys('1234')
time.sleep(1)
isagres = driver.find_element_by_name('isAgree');
ActionChains(driver).move_to_element(isagres).double_click().perform();
time.sleep(1)
driver.find_element_by_id('TANGRAM__PSP_3__submit').click();
警告框处理
在WebDriver中处理JavaScript所生成的alert/confirm/prompt十分简单,具体做法是使用 switch_to.(alert/confirm/prompt),然后使用text/accept/dismiss/send_keys等方法进行操作。
text :返回 alert/confirm/prompt 中的文字信息。
accept() :接受现有警告框。
dismiss() :解散现有警告框。
send_keys(keysToSend) :发送文本至警告框。keysToSend:将文本发送至警告框。
[图片上传失败...(image-d590d8-1515987136052)]
from selenium import webdriver
from selenium.webdriver.support.select import Select
from selenium.webdriver.common.action_chains import ActionChains
import time
driver = webdriver.Chrome();
driver.implicitly_wait(100)
driver.get("http://www.baidu.com")
setting = driver.find_element_by_link_text('设置')
ActionChains(driver).move_to_element(setting).perform();
driver.find_element_by_link_text('搜索设置').click();
time.sleep(0.5) # 不要操作过快
# 下拉框设定
DownSel = driver.find_element_by_xpath("//select[@name='NR']")
Select(DownSel).select_by_value('20');
# 保存设置
time.sleep(0.5) # 不要操作过快
driver.find_element_by_class_name("prefpanelgo").click();
time.sleep(0.5) # 不要操作过快
driver.switch_to_alert().accept();
上传文件
对于通过input标签实现的上传功能(注意这个input type一定是file), 可以将其看作是一个输入框,通过send_keys()指定本地文件路径的方式实现文件上传即可
[图片上传失败...(image-25c3d7-1515987136052)]
from selenium import webdriver
from time import sleep
driver = webdriver.Chrome();
driver.implicitly_wait(100)
driver.get("http://tuchuang.org/")
driver.find_element_by_id('add').click();
sleep(1)
driver.find_element_by_id('file_list').send_keys("C:\\Users\\wangyang37\\Desktop\\test.png");
driver.find_element_by_id('submit').click();
cookie操作
有时候我们需要验证浏览器中cookie是否正确,真实的cookies是无法满足白盒和集成测试进行的。WebDriver提供了操作Cookie的相关方法,可以读取、添加和删除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
from time import sleep
driver = webdriver.Chrome();
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")
# 打印所有cookies
cookies = driver.get_cookies();
print(cookies);
# 添加新的cookies 防止报错
cookie_list = {'name':'elan', 'key':'selenium1', 'value': 'auto-process'};
driver.add_cookie(cookie_list)
for cookie in driver.get_cookies():
print("%s -> %s" % ( cookie['name'], cookie['value'] )) # name -> value 是固定的
# 删除所有cookies
cookies = driver.delete_all_cookies();
print(cookies);
调用javascript
在浏览器没有提供相应的操作方法,我们可以使用javascript,比如借助JavaScript来控制浏览器的滚动条。WebDriver提供了execute_script()方法来执行JavaScript代码。
window.scrollTo(0,450);
window.scrollTo()方法用于设置浏览器窗口滚动条的水平和垂直位置。方法的第一个参数表示水平的左间距,第二个参数表示垂直的上边距
from selenium import webdriver
from time import sleep
driver = webdriver.Chrome();
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")
# 如果设置太小就会 unknown error: Element is not clickable at point
driver.set_window_size(800, 500);
driver.find_element_by_id("kw").send_keys("hello world");
sleep(1);
driver.find_element_by_id("su").click();
sleep(1);
# 滚轴 x(横向滚动):400 y(纵向滚动):300
js="window.scrollTo(400,300);"
driver.execute_script(js);
sleep(1);
窗口截图
from selenium import webdriver
from time import sleep
driver = webdriver.Chrome();
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")
# 如果设置太小就会 unknown error: Element is not clickable at point
driver.set_window_size(800, 500);
driver.find_element_by_id("kw").send_keys("hello world");
sleep(1);
driver.find_element_by_id("su").click();
driver.get_screenshot_as_file("C:\\Users\\wangyang37\\Desktop\\files\\hello_world.jpg")
#driver.get_screenshot_as_file("C:\\Users\\wangyang37\\Desktop\\files\\hello.png")