selenium学习笔记(基于Python)

一、windows下安装及环境配置

  1. Python安装,本文中安装的是2.x版本。去下载
  2. 配置环境变量:我的电脑-属性-高级系统设置-环境变量,将以下变量加入Path中

C:\Python27;C:\Python27\Scripts

  1. 检查python是否正确安装和配置:
    Win+R输入cmd或powershell,命令行输入“python”检查,出现Python 2.7.x...等字样表示安装配置完成
  2. 安装selenium:使用pip命令(最新版python 2.7或3.6都默认带有pip),命令行输入以下命令即可

pip install selenium

  1. 下载webdriver,解压后放在path环境变量的路径下,或者与python脚本放在同一文件夹下
    Chrome驱动,各版本的文件夹中notes.txt标注了支持的Chrome版本,根据自己安装的Chrome版本选择即可
    Firefox驱动,直接下载最新版本使用
    Edge驱动
    Safari驱动

二、知识储备

  1. html+css基础
  2. javascript基础,需要在脚本中执行js
  3. python基础,以及unittest框架

三、简介

最基础的用法如下:

from selenium import webdriver    #导入webdriver
driver = webdriver.Firefox()      #创建实例并打开浏览器,此处为Firefox
driver.get("www.google.com")      #get(url)方法打开指定URL
assert “Google” in driver.title   #断言检测页面title是否为期望值
driver.close()                    #关闭当前浏览器窗口
driver.quit()                     #关闭浏览器并退出webdriver

利用unittest的test suite方式:
1、针对待测事物写test case,继承TestCase类,定义test_xxx方法
2、在各test代码后面构造测试集,并调用runner执行测试,如:

if __name__ == "__main__":
    suite = unittest.TestSuite()
    suite.addTest(test_xxx())
    ...
    runner = unittest.TextTestRunner()
    runner.run(suite)

3、创建一个执行所有用例的文件,例如:

import unittest
import testCaseA, testCaseB...
suite = unittest.TestSuite()
suite.addTest(testCaseA.testXxx())
suite.addTest(testCaseB.testXxx())
if __name__ == '__main__':
    runner = unittest.TextTestRunner()
    runner.run(suite)

四、元素的定位

1.基础定位方式有如下几种:

  • find_element_by_id —— 通过id定位
  • find_element_by_name —— 通过name定位
  • find_element_by_class_name —— 通过class name定位
  • find_element_by_link_text —— 通过link text定位
  • find_element_by_partial_link_text —— 通过匹配部分link text定位
  • find_element_by_tag name —— 通过tag name定位
  • find_element_by_xpath —— 通过xpath定位
  • find_element_by_css selector —— 通过CSS选择器定位,推荐

2.定位元素组

使用find_elements_by_xxx方法,常用于批量操作对象,如勾选所有checkbox,例:

# 选择所有的checkbox并全部勾上
checkboxes = dr.find_elements_by_css_selector('input[type=checkbox]')
for checkbox in checkboxes:
        checkbox.click()

# 选择页面上所有的input,然后从中过滤出所有的checkbox并勾选之
inputs = dr.find_elements_by_tag_name('input')
for input in inputs:
        if input.get_attribute('type') == 'checkbox':
                input.click()

# 把页面上最后1个checkbox的勾给去掉
dr.find_elements_by_css_selector('input[type=checkbox]').pop().click()

3.层级定位

层级定位:实际项目中有很多个属性基本相同的元素,需要具体定位到其中的一个,这时需要先定位父元素,然后再定位到子孙元素,如:find_element_by_id('parent').find_element_by_id('child')

4.button group按钮组

定位思路是先找到button group的div,然后通过层级定位,用index或者属性去定位具体的按钮,例:

# 定位text是second的按钮
buttons = dr.find_element_by_class_name('btn-group').find_elements_by_class_name('btn')
for btn in buttons:
    if btn.text == 'second': print 'find second button'

5.button dropdown

button dropdown按钮把按钮和下拉菜单放在一起,处理思路是先点击这个按钮,等待下拉菜单显示后,通过层级定位获取下拉菜单中的选项,例:

#点击下拉菜单
dr.find_element_by_link_text('Info').click()

#找到dropdown-menu父元素
WebDriverWait(dr,10).until(lambda the_driver: the_driver.find_element_by_class_name('dropdown-menu').is_displayed())

#找到better than
menu = dr.find_element_by_class_name('dropdown-menu').find_element_by_link_text('better than')

6.navs

navs用于简单的tab导航栏,通常先定位ul再层级定位到li即可,或者直接根据link_text定位

7.面包屑

面包屑一般来说当前层级都没有链接,而副层级基本是链接,所以思路基本上是:先找到面包屑所在div或ul,再找到其下所有链接,这些链接就是父层级,最后不是链接的就是当前层级了

8.分页

一般分页需要知道的是:总共的页数,当前页数,是否可以上下翻页,或者直接跳转
分页通常使用ul来实现,当前页一般是没有链接的,通过class name = active定位,其它2个信息按页面情况获取

四、元素的操作:

1.获取对象的属性及内容

通过webdriver的element.attribute()方法获取dom元素属性
获取css属性:element.value_of_css_property()

2.获取对象的状态

通常需要获取对象的四种状态:

  • 是否显示——使用element.is_displayed()
  • 是否存在——使用find_element_by_xxx方法,捕获抛出的一场,如果存在异常则不存在
  • 是否被选中——一般是判断表单元素是否被选中,如radio或checkbox,通过element.is_selected()方法
  • 是否enable——使用element.is_enabled()

3.一些基本的操作

  • click() 点击对象
  • send_keys() 在对象上模拟按键输入或往文本框赋值(需要form selenium.webdrive.common.keys import Keys
  • clear() 清除对象内容
  • submit() 用于提交表单,特别用于没有提交按钮的情况,比如搜索框输入关键字后按回车搜索的(也可以通过模拟回车键来实现)

4.执行js

通常需要在页面上或者定位的元素上执行js,而webdriver就提供了execute_script()接口来执行js
js = "some javascripts"
driver.execute_script(js)

5.等待

在页面进行操作致使一些元素隐藏或出现时,或者等待ajax执行完成时,需要用到WebDriverWait的until方法等待(显式等待),需要用到的是selenium.webdriver.support.ui.WebDriverWait类,until方法会一直等下去,直到

  • 代码块中的内容为true(不为false或没有抛出异常)
  • 超时,即超过timeout设定的时间

例如等待直到某元素显示

wait = selenium.webdriver.support.ui.WebDriverWait(driver, 10)
wait.until(lambda driver: driver.element.isdisplayed())            #lambda为Python创建匿名函数的关键字

隐式等待,是指通过一定的时长等待页面所有元素加载完成,如果超出了设置的时长而元素还没有被加载则抛出NoSuchElementException异常。WebDriver提供了implicitly_wait()方法来实现隐式等待,默认设置为0.

6.复杂的操作

1. ActionChains模拟鼠标操作
  • perform() 执行所有ActionChains中存储的行为
  • context_click() 右击
  • double_click() 双击
  • drag_and_drop() 拖动
  • move_to_element() 鼠标悬停
2.frame切换

页面嵌套frame时,若要定位frame中的元素,需要通过switch_to_frame(id/name)方法先将定位主体切换到frame里。
如果iframe没有id或name可以定位,则先通过其它方式先定位到frame,再将定位对象传给switch_to_frame()方法。
如果完成了在当前frame上的操作,可以通过switch_to_default_content()方法返回上一层表单。

3.多窗口切换

通过switch_to_window()方法切换到任意窗口。
current_window_handle——获得当前窗口句柄
window_handles——返回所有窗口的句柄到当前会话
switch_to_window(handle)——根据给的句柄切换到相应窗口

4.警告框处理

处理JS生成的alert、confirm以及prompt做法是通过switch_to_alert()方法定位到alert/confirm/prompt,然后使用text/accept/dismiss/send_keys执行对应操作

  • text 返回提示框中的文字信息
  • accept 点击确认按钮
  • dismiss 点击取消按钮(当存在取消按钮时可用)
  • send_keys 输入值(仅prompt可用)
5.文件上传
  1. 对于用过input标签实现的上传,可以将其看作一个输入框,通过send_keys()传入本地文件路径从而模拟上传功能。
  2. 借助Autolt实现上传。首先通过AutoIt写好脚本并转换成exe可执行文件,然后在python中,打开上传文件对话框,再调用os.system('xxx.exe')运行exe来实现上传。
6.文件下载
  1. 通过编辑配置文件将文件下载到默认路径
  2. 通过AutoIt脚本实现
7.操作cookie
  1. get_cookies() 获得所有cookie信息
  2. get_cookie(name) 返回有特定name值得cookie信息
  3. add_cookie(cookie_dict) 添加cookie,必须有name和value值
  4. delete_cookie(name) 删除特定部分的cookie信息
  5. delete_all_cookies() 删除所有的cookie信息
8.窗口截图

webdriver提供了截图函数get_screenshot_as_file()来截取当前窗口

五、遇到的一些坑

  1. 使用Chrome,登陆后总是弹出记住密码提示框——解决办法:打开Chrome时设置option选项:
options = webdriver.ChromeOptions()
prefs = {"":""}
prefs["credentials_enable_service"] = False
prefs["profile.password_manager_enable"] = False
options.add_experimental_option("prefs",prefs)
driver = webdriver.Chrome(chrome_options = options)
  1. 根据关键词搜索结果的断言,思路是获取搜索结果集,遍历判断对应列的text是否包含关键词,包含则count++,最后判断count与搜索结果总数是否相等(这个想法太蠢了,用循环遍历每个搜索结果,并assert判断是否等于或包含,一个用例可以包含多个断言的,每个断言是并行的,所有assert都通过,结果才是通过的)
    问题一:搜索结果较多,分页怎么获取正确数量

  2. 遇到一个案例,浏览器点击当前页面A元素,打开了新的标签页B之后,实际的window句柄还是在当前A页面,而我想当然以为是新标签页B,然后定位B中的元素发现死都找不到。。。所以如果有打开新的页面,还是需要通过switch_to.window(handler)切换到新的页面

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容