一、安装
-
安装selenium
在安装python后,直接在命令行执行pip install selenium
即可自动安装selenium -
浏览器驱动安装
Chrome浏览器驱动下载地址:http://npm.taobao.org/mirrors/chromedriver/
Firefox浏览器驱动下载地址:https://github.com/mozilla/geckodriver/releases/将chromedriver.exe , geckodriver.exe , Iedriver.exe放到Python的安装目录,例如 D:\python 。 然后再将Python的安装目录添加到系统环境变量的Path下面。
IE浏览器的兼容性不太好,推荐使用谷歌或者狐火浏览器做自动化开发
-
尝试用代码启动浏览器,检查是否安装成功
启动谷歌浏览器
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('http://www.baidu.com/')
启动火狐浏览器
from selenium import webdriver
browser = webdriver.Firefox()
browser.get('http://www.baidu.com/')
启动IE浏览器
from selenium import webdriver
browser = webdriver.Ie()
browser.get('http://www.baidu.com/')
Selenium原理
转自 https://www.cnblogs.com/linuxchao/p/linux-selenium-webdriver.html
1,执行测试脚本webdriver.Chrome()会自动执行chromedriver.exe驱动程序,开启一个进程
2,通过RemoteWebDriver向浏览器驱动程序发送HTTP请求,浏览器驱动程序解析请求,打开浏览器,并获得sessionid,如果再次对浏览器操作需携带此id
3,打开浏览器,绑定特定的端口,把启动后的浏览器作为webdriver的remote server
4,打开浏览器后,所有的selenium的操作(访问地址,查找元素等)均通过RemoteConnection链接到remote server,然后使用execute方法调用_request方法通过urlib3向remote server发送请求
5,浏览器通过请求的内容执行对应动作
6,浏览器再把执行的动作结果通过浏览器驱动程序返回给测试脚本
二、元素定位的方法
1、id定位:
find_element_by_id()
2、name定位:
self.driver.find_element_by_name('name').send_keys('XXX')
3、class_name定位:
self.driver.find_element_by_class_name('icon.lanap').click()
4、tag定位:
find_element_by_tag_name()
如果懂HTML知识,我们就知道HTML是通过tag来定义功能的,比如input是输入,table是表格,等等。每个元素其实就是一个tag,一个tag往往用来定义一类功能
5、link定位:
find_element_by_link_text('官方网站')
此种方法是专门用来定位文本链接的
6、partial_link定位:
find_element_by_partial_link_text()
7、xpath定位:
在谷歌浏览器中按F12,选择Elements页面,可以看到html的代码
选择一个元素后,右键,可以获取到该元素的xpath
find_element_by_xpath()
三、Webelement常用方法
- 点击和输入
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=driver.find_element_by_id('kw')
search_text.send_keys('selenium')
search_text.submit()
- 其他
size: 返回元素的尺寸。
text: 获取元素的文本。
dns1=self.driver.find_element_by_xpath('//*[@id="wanStatusContent"]/tr[2]/td[1]/dl/dd').text
get_attribute(name): 获得属性值。
is_selected() 判断是否被选中
is_displayed(): 设置该元素是否用户可见。
- 关闭浏览器
close() 关闭单个窗口
quit() 关闭所有窗口
- 窗口最大化:
self.driver.maximize_window()
四、开发中常用到的一些问题总结
1,元素隐藏
- 当定位的元素被隐藏的时候,
driver.find_element_by_xx().is_displayed()
,返回FALSE
。 - 此时用text属性,无法获取到文本值,需要使用
textContent, innerText, innerHTML
等属性获取 - 例如,
<div>Hello <p>World!</p></div>
的innerHTML会得到Hello <p>World!</p>
- textContent 和 innerText 只会得到文本内容,而不会包含 HTML 标签。
- -innerHTML 会返回元素的内部 HTML, 包含所有的HTML标签。
textContent 是 W3C 兼容的文字内容属性,但是 IE 不支持
innerText 不是 W3C DOM 的指定内容,FireFox不支持
self.dut.driver.find_element_by_class_name('t.error').get_attribute('textContent')
2,class定位
当classname 中存在空格的时候,直接使用find_element_by_class_name
时,会显示定位失败,此时,需要将classname中的空格替换成英文的点“.”
self.dut.driver.find_element_by_class_name('t.error').get_attribute('textContent')
3,切换窗口
#获取所有窗口句柄
handles=self.dut.driver.window_handles
#切换窗口
self.dut.driver.switch_to.window(handles[-1])
4,模糊定位
通过contians进行模糊定位,‘.’ 表示任何类型的元素
self.dut.driver.find_element_by_xpath('//*[contains(.,"服务热线 400-100-5678")]')
self.driver.find_element_by_xpath('//*[contains(text(),"互联网")]').click()
5,刷新页面
self.dut.driver.refresh()
6,clear命令不生效
当clear命令不生效的时候,可以模拟键盘事件,全选,删除
self.driver.find_element_by_xpath('').send_keys(Keys.CONTROL,'a')
time.sleep(1)
self.driver.find_element_by_xpath('').send_keys(Keys.BACK_SPACE)
7,xpath中包含单引号、双引号时候的处理
- 当想要查找的文本中只包含单引号,可以选择用双引号包裹文本
driver.find_element_by_xpath('//*[contains(text(),"12\'34")]')
- 当想要查找的文本中只包含双引号的时候,可以选择用单引号包裹文本
driver.find_element_by_xpath('//*[contains(text(),\'12"34\')]')
- 当文本中同时包含单双引号的时候,需要使用concat()函数重新连接字符串
如:driver.find_element_by_xpath('//*[contains(.,concat("3",\'"\',"7","\'","8"))]')
当文本中的引号位置不确定的时候,用以下函数来处理下字符串就不会报错了
def xpath_doble_quote_replace(self,str1):
# xpath中包含单双引号时候的处理
alist = list(str1)
str2 = ''
for i in range(len(alist)):
if alist[i] == '"':
alist[i] = "'\"',"
elif alist[i] == "'":
alist[i] = '"\'",'
else:
alist[i] = '"%s",' % alist[i]
alist[-1] = alist[-1].replace(',', '')
str2 = ''.join(alist)
a = 'concat(%s)' % str2
return a
driver.find_element_by_xpath('//*[contains(.,%s)]'%xpath_doble_quote_replace('3"7\'8'))
8,组合定位
先确定一个范围,在里面查找对应属性匹配的element
self.driver.find_element_by_xpath('//*[@id="selOptsUlchannel"]/li[@title="%s"]' % option['channel'])
self.driver.find_element_by_xpath('//*[@id="dummydata"]/a[.="%s"]'%option['pro'])
self.driver.find_element_by_xpath('//*[@id="vpnlist"]/tr[contains(.,"%s")]/td[6]/div[1]' % name)
9,内置页面的滚动
拖动内置页面滚动条,将内置页面滚动(x,y)的位移
from selenium.webdriver import ActionChains
Drag = self.driver.find_element_by_xpath('//*[contains(@id,"selOptsUlchannelniceScrollSb")]/label')
ActionChains(self.driver).drag_and_drop_by_offset(Drag, 0, value).perform()
10,切换frame
- 当一个元素的路径正确,确怎么也无法定位的时候,很可能是没有切换到正确的frame
(frame中实际上是嵌入了另一个页面,而webdriver每次只能在一个页面识别,因此需要先定位到相应的frame,对那个页面里的元素进行定位。)
(1)如果iframe有name或id的话,直接使用switch_to_frame(“name值”)或switch_to_frame(“id值”)
self.driver.switch_to.frame('page')
(2)如果iframe没有name或id的话,则可以通过下面的方式定位:
#先定位到iframe
elementi= driver.find_element_by_class_name('APP-editor-iframe')
#再将定位对象传给switch_to_frame()方法
driver.switch_to_frame(elementi)
11, jenkins执行selenium 测试 浏览器不显示
(1)在任务管理器中,停掉Jenkins服务;修改启动模式为禁用
(2)在命令行启动jenkins java -jar “D:\Program Files (x86)\Jenkins\jenkins.war”
(3)重新创建job
12, selenium 文件下载不弹出窗口
火狐浏览器
profile = webdriver.FirefoxProfile()
profile.set_preference('browser.download.dir', data.down_load_dir) # 指定下载路径
profile.set_preference('browser.download.folderList', 2) # 设置成 2 表示使用自定义下载路径;设置成 0 表示下载到桌面;设置成 1 表示下载到默认路径
profile.set_preference('browser.download.manager.showWhenStarting', False) #在开始下载时是否显示下载管理器
profile.set_preference('browser.helperApps.neverAsk.saveToDisk', 'application/x-gzip')
self.driver=webdriver.Firefox(firefox_profile=profile) # 对所给出文件类型不再弹出框进行询问
Firefox需要针对每种文件类型进行设置,这里需要我们查询对应文件的MIME类型,可以用以下链接进行查询:MIME 参考手册 https://www.w3school.com.cn/media/media_mimeref.asp
谷歌浏览器默认就没有弹窗,可以下载到设置的默认目录,如果不行的,可以试试下面的设置
# -*- coding: utf-8 -*-
from selenium import webdriver
from time import sleep
options = webdriver.ChromeOptions()
prefs = {'profile.default_content_settings.popups': 0, 'download.default_directory': 'd:\\'}
options.add_experimental_option('prefs', prefs)
driver = webdriver.Chrome(executable_path='D:\\chromedriver.exe', chrome_options=options)
driver.get('http://sahitest.com/demo/saveAs.htm')
driver.find_element_by_xpath('//a[text()="testsaveas.zip"]').click()
sleep(3)
driver.quit()
详见:https://blog.csdn.net/weixin_36886116/article/details/83026235
13,Python selenium父子、兄弟、相邻节点定位方式详解
详见:
https://blog.csdn.net/huilan_same/article/details/52541680
14,selenium + Python 上传文件
(1)input标签是可以直接send_keys
upload=self.driver.find_element_by_id('configimage')
upload.send_keys(file) # file表示文件的路径+文件名
(2)非input型上传
https://www.jianshu.com/p/fba37cc5d5e2
15. js注入
某个元素在实际的操作过程中被其他的元素遮挡,就可以使用 js注入的方式进行点击
ele = self.dut.driver.find_element(by=By.ID, value='statusWifi')
self.dut.driver.execute_script("arguments[0].click();", ele)