selenium+phantomjs自动化脚本的一个例子

selenium

selenium是一个用于Web应用程序测试的工具。selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IEMozilla FirefoxChrome等。

phantomjs

phantomjs是一个服务器端的JavaScript APIWebKit。其支持各种Web标准: DOM处理, CSS选择器, JSON, Canvas, 和SVG

用途

  1. Web测试
  2. 数据抓取、页面截图
  3. 涉及到Web操作的自动化脚本

安装phantomjs

使用官方提供的linux x86_64二进制包:

wget -c "https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2" -O /dist/dist/phantomjs-2.1.1-linux-x86_64.tar.bz2  
cd /dist/dist  
tar xvf phantomjs-2.1.1-linux-x86_64.tar.bz2  
cp -v phantomjs-2.1.1-linux-x86_64/bin/bin/phantomjs /usr/local/bin/phantomjs  

安装selenium

selenium支持多种语言,这里我选择了我们比较熟悉的python,直接用pip或者easy_install安装即可:

pip install selenium  

第一个脚本

from selenium import webdriver  
driver = webdriver.PhantomJS()  
driver.get("http://www.baidu.com")  
print driver.title  
driver.quit()  

如果正常,可以看到输出:

百度一下,你就知道

大部分操作都是在webdriver上执行的,上面的例子是访问网页(get),然后打印出当前网页的title(driver.title)。下面介绍下常用的函数和属性。

常用的selenium函数和属性

webdriver

调用不同的浏览器

driver = webdriver.Firefox()  
driver = webdriver.Chrome()  
driver = webdriver.Ie()  
driver = webdriver.Opera()  
driver = webdriver.PhantomJS()  

设置等待网页加载时间

在一些情况下,某些网页资源未正常加载,可以设置一个等待时间,不让driver卡在加载中

driver.set_page_load_timeout(seconds)  

设置js脚本或者DOM加载超时时间

如上所述

driver.implicitly_wait(seconds)  

当前url

driver.current_url  

网页源码

driver.page_source  

退出浏览器driver

driver.quit()  

操作Web控件

DOM查找

查找DOM控件,返回第一个找到的控件,下面的每个函数,还有同样的find_elements*函数,返回的是所有符合条件的列表。

driver.find_element(by='id', value=None)  
driver.find_element_by_class_name(name)  
driver.find_element_by_css_selector(css_selector)  
driver.find_element_by_id(id_)  
driver.find_element_by_link_text(link_text)  
driver.find_element_by_name(name)  
driver.find_element_by_partial_link_text(link_text)  
driver.find_element_by_tag_name(name)  
driver.find_element_by_xpath(xpath)  

点击

点击控件,比如button、超链接等控件

element.click()  

输入文本

inputtextarea类控件中输入文本

element.send_keys(some_strings)  

还有非常多函数和属性,不过我也没有使用过,有兴趣的可以看文档

一个实际例子

QCloud没有提供CDN预热的API,无奈之下,用selenium+phantomjs实现了脚本化操作预热的功能。

我们从登录页面https://console.qcloud.com开始:

初始化

import time  
from selenium import webdriver  
# 因为是https访问,因此加上两个参数避免出错
driver = webdriver.PhantomJS(service_args=['--ignore-ssl-errors=true', '--ssl-protocol=any'])  
driver.implicitly_wait(30)  
driver.set_page_load_timeout(30)  

登录

很多管理类的网页都是需要登录才能操作的,一般都是如下面这种登录框:

在登录框上右键点击,选择查看框架的源代码(Chrome,其他浏览器也有对应的功能)

可以抓到登录链接:

https://ssl.xui.ptlogin2.qcloud.com/cgi-bin/xlogin?hide_title_bar=1&bgcolor=ffffff&no_verifyimg=1&link_target=blank&style=22&appid=543009503&target=self&s_url=https://passport.qcloud.com/index/forward&enable_qlogin=1  

请求登录页面:

driver.get('https://ssl.xui.ptlogin2.qcloud.com/cgi-bin/xlogin?hide_title_bar=1&bgcolor=ffffff&no_verifyimg=1&link_target=blank&style=22&appid=543009503&target=self&s_url=https://passport.qcloud.com/index/forward&enable_qlogin=1')  

在用户名输入框上右键点击,选择检查,可以审查元素:

可以看到id="u",使用find_element_by_id函数找到该控件:

user_elm = driver.find_element_by_id('u')  

同样,密码框和登录按钮也可以用这种方法获取:

pass_elm = driver.find_element_by_id('p')  
button = driver.find_element_by_id('login_button')  

找到控件,就可以用send_keys输入用户名和密码:

user_elm.send_keys('your_QQ_number')  
pass_elm.send_keys('secret_password')  

然后点击登录按钮:

button.click()  

然后我们看下是不是已经登录了:

print driver.current_url  
# 输出:https://www.qcloud.com/
print driver.page_source  
import re  
print re.search(r'class="sign-in-links">(.*?)</a>', driver.page_source).group(1)  
# 这里应该会输出你的用户名

进入CDN控制页面

登录后我们可以直奔主题:https://console.qcloud.com/cdn/refresh

driver.get("https://console.qcloud.com/cdn/refresh")  

进入URL预热链接

然后我们在页面上审查下元素:

这里是个链接

使用find_element_by_link_text获取链接控件:

preheat_link = driver.find_element_by_link_text(u"URL预热")  

然后点击:

preheat_link.click()  

输入框和预热按钮

现在,我们需要找到页面下方的大输入框(textarea)然后填充我们需要预热的URL:

这里没有id属性了,我们可以用xpath查找,在审查元素的文本上右键选择Copy->Copy XPath

得到控件的xpath

//*[@id="appArea"]/div[2]/div/div/div/div[3]/table/tbody/tr/td/textarea

使用find_element_by_xpath函数查找控件:

textarea = driver.find_element_by_xpath('//*[@id="appArea"]/div[2]/div/div/div/div[3]/table/tbody/tr/td/textarea')  

现在我们就可以填充需要预热的URL了:

textarea.send_keys('http://xxxx/xxx.zip')  

使用同样的方法查找预热按钮(页面中的提交并预热按钮):

preheat_button = driver.find_element_by_xpath('//*[@id="appArea"]/div[2]/div/div/div/div[3]/div[2]/button')  

然后点击预热按钮:

preheat_button.click()  

退出driver

driver.quit()  

以上就是整个流程。

其他

phantomjs还可以用来网页截图,如下:

from selenium import webdriver  
driver = webdriver.PhantomJS()  
driver.set_window_size(1024, 768)  
driver.get('https://github.com')  
driver.save_screenshot('github.png')  

对于一些图表较多的Dashboard,可以操作截图然后发送邮件,作为报表来存档。