运维人员烦恼的开始
你曾经是否有这样的境遇:日常运维的一个WEB平台,每天都要进行一些繁琐的操作,需要你用鼠标键盘不停的去点点点,有时候这些操作是高度重复的,或者是零零碎碎的分散时间需要你去操作。就拿监控工具zabbix的维护期来说(zabbix是再常见不过的监控工具了),遇到公司各大平台变更集中的时间段,每个平台负责人都会向你提出维护期申请,最令人烦恼的是,不同的申请人提出的时间不同、平台不同。于是你从早到晚的加了上百个维护期,怕自己加错了还把每个维护期检查了一遍,手点的都抽筋了,脑子也很混沌了,抬头一看表晚上七点,一天就加了点维护期,领导又要批评自己了。这时候有人会说:”用zabbix-API添加维护期啊,写写python不就可以自动加了吗!”奈何自己技术糙,又不想看全是文英并且传参很麻烦的API文档,甚至某些场景你都没有API的详细说明!!那怎么办呢?使用Selenium吧!
首先看一下Selenium的效果:
引用官网的一句话:"Selenium测试直接运行在浏览器中,就像真正的用户在操作一样"。是啊,如果用selenium帮你干这些活,那你可以去腾出更多的时间去学习与工作。其实上面的过程放在代码里,主要就是分为三步走:
首先需要打开一个你想操作的网页,然后再选定该网页上的HTML元素,再对该元素进行一些列操作,做好这三步,就可以做出上面动图的效果!
支持的开发环境
语言:C、java、ruby、python、JS或者是C#
平台:linux、windows、MAC
浏览器:ie、Firefox、Safari、Opera、Chrome
所以,拿你常用的语言,常用的浏览器去开发调试,没有太大的限制条件(本文将用python +Chrome进行示范)。
First-快速上手
通过pip install selenium安装。
下载Chrome对应版本的WebDriver( 点击下方阅读原文即可跳转)
编写代码:
from selenium import webdriver
import time
if __name__ == '__main__':
chrome_driver = 'C:\\xxx\\Google\\Chrome\\Application\\chromedriver.exe' # chromedriver的文件位置
driver = webdriver.Chrome(executable_path=chrome_driver)
driver.get('https://www.baidu.com')
driver.find_element_by_id('kw').send_keys('Hello,')
time.sleep(1) # 为了方便展示加了点延迟
driver.find_element_by_id('kw').send_keys('光大科技')
driver.find_element_by_id("su").click()
通过上述简单的插件安装与几行python代码,就实现了自动打开“百度”,输入”Hello,光大科技“,并点击搜索的功能,是不是简洁至极!值得一提的是,这是Selenium的有操作界面启动模式,即可以看到它执行过程中的操作页面,点击了哪里都可以看到。但是我们大部分Linux服务器可是没有操作界面的呀!是的,还有一种模式叫Headless启动模式,可以在不打开浏览器的前提下,使用所有Chrome支持的特性运行你的程序。相比于现代浏览器,Headless Chrome更加方便测试web应用,获得网站的截图,做爬虫抓取信息等。相比于较早的PhantomJS、SlimerJS等,Headless Chrome则更加贴近浏览器环境。
Second-元素定位
看完上面的快速开始,可能你还不知道,为什么代码可以执行输入、搜索这些功能。其实这都归功于元素的定位,并对定位后的元素进行一些操作执行,就例如上面的:
driver.find_element_by_id('kw')driver.find_element_by_id("su")
选择id为"kw"与"su"的元素,百度搜索首页HTML内容如下:
其实就是通过选定HTML上的元素ID “kw”(即百度搜索输入框input),然后再输入了“光大科技”这个String。熟悉前端的开发人员应该对HTML的元素并不陌生,老牌劲旅JQuery中就有常用的元素选择器,如ID选择器$("#id"),类选择器$(".className")等等,find_element_by_id('kw')就是通过选择ID元素来进行元素定位的。这时前端开发的同学又要说了:“JQuery我早就不用了!现在都用火爆的三大框架,网页哪有那么多元素绑定ID?”。是的,但是不要慌,webdriver提供了很多元素定位方法,不只是绑定ID:
id定位:find_element_by_id()
name定位:find_element_by_name()
class定位:find_element_by_class_name()
link定位:find_element_by_link_text()
partial link定位:find_element_by_partial_link_text()
tag定位:find_element_by_tag_name()
xpath定位:find_element_by_xpath()
css定位:find_element_by_css_selector()
id、name、class这些就不用多说了,直接选定就可以用。link定位,此种方法是专门用来定位文本链接的,比如百度首页右上角有“新闻”,“hao123”,“地图”等链接。如果懂HTML知识,我们就知道HTML是通过tag来定义功能的,比如input是输入,table是表格,等等。每个元素其实就是一个tag,一个tag往往用来定义一类功能,我们查看百度首页的html代码,可以看到有很多div、input、a等tag,所以很难通过tag去区分不同的元素,这个不常用。其中,个人认为功能最强大的是xpath定位,find_element_by_xpath(),它是基于HTML文档目录结构进行元素定位的(html的DOM树),理论上可以通过路径、索引、属性值、轴定位、文本test定位到几乎全部的元素,听起来就很强,但是用法也相对其他方法复杂一点点,且要具备HTML DOM的知识,举几个常用的例子如下:
多元素属性值定位(相对路径):xpath= "//标签名[@type='XX' and @name='XX']" (type、name均为属性名)
绝对路径定位:xpath = " /html/body/div/标签名[@属性="属性值"]"(定位到body下的某个div下的元素,如果div很多,可以通过div[@属性值="xx"]来具体到某个div),但是绝对路径方法维护成本太高,一般不用
test()文本定位:xpath = "//标签名[text()='上一步']"
索引定位:xpath = "//标签名[2]"如 //input[2]定位到body中第三个input标签
轴定位:用::表示,选择当前节点的父节点(parent)、子节点(child)、祖先节点(ancestor)、子孙节点(descendant)、后节点(following)前节点(preceding)、后兄弟节点(following-sibling)、前兄弟节点(preceding-sibling)xpath="//标签/关系关键字::标签",如//div[1]/child::img,就是寻找div[1]的子节点img
Xpath方法还是需要多用,多见见复杂的html dom结构,在实战中提升使用技巧,对于定位而言它几乎是万能的,有兴趣的同学可以仔细研究研究~
html dom树结构参考
- 左右滑动查看更多 -
图片来源于网络
third-操作方法
通过上面的元素定位,现在同学们已经可以随心所欲的定位自己想要的元素了,那接下来就应该对所取元素进行一些快乐的操作!就如开始的demo中:
driver.find_element_by_id('kw').send_keys('Hello,')driver.find_element_by_id("su").click()
上面.send_keys().click()就是响应的元素操作,对你选中的元素进行传值、点击等等。
总结了一下相关操作方法,以百度搜索首页为例,进行操作:
driver.find_element_by_name('wd').send_keys(‘PythonSelenium’),#在百度文本搜索框内输入内容Python Seleniumdriver.find_element_by_name('wd').clear(),#清空文本搜索框的所有内容driver.find_element_by_id('su').click(),#点击搜索按钮driver.find_element_by_id('su').submit(),#提交搜索按钮,这里效果同点击搜索按钮driver.find_element_by_id('kw').size,#获取搜索框的大小driver.find_element_by_id('jgwab').text,#获取控件id为’jgwab’所显示的内容driver.find_element_by_id('su').get_attribute('type'),#获取控件id为’su’的属性,例如button,radio等driver.find_element_by_name('wd').is_displayed(),#判断搜索文本框当前是否被显示
当然也不只有简单的点点点,只要是日常操作鼠标键盘能实现的(模拟键鼠操作),Selenium都可以实现,举例如下:
driver.find_element_by_id('kw').send_keys(Keys.BACK_SPACE)#Backspace键driver.find_element_by_id('kw').send_keys(Keys.SPACE)#Space键driver.find_element_by_id('kw').send_keys(Keys.DELETE)#Delete键driver.find_element_by_id('kw').send_keys(Keys.CONTROL,'a')# CTRL + AActionChains(driver).context_click(driver.find_element_by_id('kw')).perform()#在搜索文本框利用context_click()进行鼠标右击,perform()是执行方法的语句ActionChains(driver).double_click(driver.find_element_by_id('kw')).perform()#在搜索文本框利用double_click()进行双击, perform()是执行方法的语句ActionChains(driver).drag_and_drop(driver.find_element_by_id('kw'),driver.find_element_by_id('su')).perform()#利用drag_and_drop(source,target)从搜索文本框移动到点击按钮,perform()是执行方法的语句
这些都是一些常用且实用的操作,相信你一定会用到!想了解更高阶玩法的小伙伴们可以自行学习~
The end-打包、使用
当你按照三步走写完你的python代码,并且运行正常,就可以执行打包.exe操作了。打包成.exe你的程序将可以在任何一台windos-pc上运行,可以发给你工作上的小伙伴,且不需要它本地安装任何依赖。(当然如果不嫌麻烦,在要执行的机器上安装好所有依赖,也可以用xxxx.py直接执行)安装打包工具pyinstaller:
执行打包命令:pyinstaller -F xxx.py(xxx.py,打包的文件),生成的exe在/项目地址/dist目录下。然后,双击,运行!
Selenium 相关其他玩法
Selenium玩爬虫
既然能选定元素并操作元素,那一定可以做爬虫吧!没错,它确实具备很多玩爬虫的优点:对比于requests玩爬虫来讲,Selenium能获取js动态给出的源码,且做到模拟真实登录减少了反爬的限制。但是缺点很明显,获得多出来的前端渲染功能是要付出代价的,requests直接不启动浏览器、不渲染动态页面,想要单位时间内爬取大量信息,性能会差很多!有时候两者结合面对反爬应该更好用一些~
Selenium IDE
它是一款依赖于Firefox浏览器的插件(xpi),可以实现脚本的录制、回放以及编辑脚本功能,元素定位等,可以利用 selenium IDE将录制的脚本生成相应的带单元测试框架的自动化测试脚本。如果只用于web自动化测试,这是一个很便捷的工具,它的页面如下。
调用JS语言
Selenium方法execute_script(script, *args),参数可以填写任何JavaScript语言,例如我们前端常用的alert()。浏览器滚动条的拖动,不能依靠WebDriver提供的API来实现,所以可以调用js中的window.scrollTo(xx,xx)来设置滚动条的位置。
其实Selenium+webdriver是为自动化测试web应用而生,但是我认为可以应用的场景很多,比如在不知道或不熟悉后端API情况下自动化的平台运维(本文举例),日常生活工作中高重复度、浪费时间的网页操作,都可以使用,有时候你也可以用它来抢折扣票、火车票等。当然为了更好的操作web,有时候可能还需要结合本地文件(比如excel,import xlrd),这样你就可以把每次需要填写的内容写在Excel中,随时修改,让python帮你完成相应的解析并输出。