近在看python的爬虫框架(scrapy),一个词概括是:"酸爽"!等把selenium自动化版块讲完后,打算写一写关于scrapy相关的知识,打算从源码角度解析下scrapy这个框架。我的想法是它不仅仅是用来爬网页的,更重要的是如何检测一个网站所有页面的健康性...回到正题,我想讲讲这个话题的起因是同事在自动化过程中遇到了flash的点击操作,查阅网上的相关资料也得不到有效解决。我想想谈谈这个flash的自动化操作问题!!
随着页面做的越来越炫酷,flash被越来越多的嵌入到html网页中。但是往往由于对flash的简单操作,却阻断了我们整个自动化的测试过程!selenium目前的版本是3.0了对flash操作仍然没有提出解决方案。其实我觉得,不是selenium不作为,而是它无能为力!!为什么这么说呢?我们知道flash是as语言开发的,我们想在网页中操作flash,那么必须通过js这个媒介来操作,问题是:开发有没有开放操作flash的js接口?我们知道js如果要调用as,那么as源码中必须使用ExternalInterface.addCallback函数,把as的接口绑定给js,这样的话我们可以轻松的调用js以达到控制flash的目的...我们搜索selenium对flash的解决方案:99.99%都是向flex工程注入SeleniumFlexAPI.swc,然后通过调用js的接口来控制flash。
对于一些IT基础比较薄弱的同学来说,始终不知道如何按照网上的步骤来进行下去,这里我对这个方案做个简单的解释如下:
1.这个是需要原flash工程的,不是你得到的一个简单的swf文件能重新编译的。简单的说是找你们开发吧,让他把SeleniumFlexAPI.swc加入到被操作Flash(Flex)的工程文件的Build库中,重新Build Flash,然后重新发布到web上。这样你对这个新的flash可能用js进行操作了。
2.SeleniumFlexAPI.swc这个文件以及好久好久没更新了...不知道是否对现在的flash能否操作有效,所以我在1中用了可能。
3.我总觉得这个方法有点脱裤子放屁的感觉,既然找开发帮你引入SeleniumFlexAPI.swc这个文件,还不如给你直接开放js接口,不是更好?
吐槽了网上的方法,来说说站在一个测试者角度的解决方案!
一、利用AutoIt
从某种意义上来说,我有点对这个工具产生依赖。当我在自动化过程中绝望的时候,我会第一时间想到它,而它也往往能带给我惊喜,像上篇用fiddler录制接口一样(其实还有很多..)!来说说我用这个工具来操作flash。我所操作的Flash图片如下:
这个Flash是有动画效果的,经过一段动画后出现上面图片的效果。我的任务是点击上面图片中的小鼠标。下面贴出来AutoIt的脚本(终转换成exe程序,在控制台中执行):
#include <MsgBoxConstants.au3>
Example()
Func Example()
Local $win = WinWait("[CLASS:MozillaWindowClass;Title:Mozilla Firefox]","",10)
WinActivate($win);激活当前窗口
$pos =WinGetPos($win)
$high=$pos[3];表示窗口的的实际高度
$weight=$pos[2];表示窗口的实际宽度
$click_x=970*$weight/1382;970表示我在当前电脑分辨率宽度为1382下的X坐标值
$click_y=540*$high/744;744表示我再当前电脑分辨率高度为744下的Y坐标值
$num=1
While 1
$icolor=PixelGetColor($click_x,$click_y)
If $icolor==6671717 Or $icolor==1321236 Or $num==5 Then
ExitLoop
EndIf
Sleep(2000)
$num=$num+1
WEnd
MouseClick("left",$click_x,$click_y,1)
EndFunc ;
需要注意的是,由于Firefox中嵌入的flash是非windows标准控件,我们只能用相对坐标来点击。关于以上坐标值得获取,依然用Autoit windows info这个工具获取如下:
而我们当前电脑分辨率下,取得的整个控件的大小信息如下:
上面脚本很简单很简单,你应该明白我什么意思。还有一点说明的是上面标红的部分。我说过了我的flash是个动画,经过大概5-6后会出现这个小鼠标。那么我们在autoit中如果动态的判断这个小鼠标出现了呢?当然你可以在脚本中Sleep(10000)等待10S钟。但是我觉得这样不太好,我的做法是:在一个循环中实时的取得我所点击区域的颜色值用PixelGetColor这个函数取得(返回的是一个十进制的值)。当我们等待的这个控件出现时,即该区域的颜色值等于某个值时,跳出这个循环,然后对这个控件用坐标进行点击!这个color的值我在第二张中也圈出了,这是个16进制的值,转换成10进制即可!上面的脚本我在2台不同的分辨率大小的电脑上测试过,基本能运行成功!!但是用autoit操作flash也是有一点的缺点。大的缺点是相对坐标计算的准确性!不过一般我觉得是没问题的。
上面第一种方案是通过autoit操作flash点击的,当然autoit也可以模拟其他我们人为的操作,比如在输入框中输入、双击某个按钮等...注意的是,对于非标准控件你要尽可能的保证相对坐标计算的准确性!
二、利用Sikuli
这个工具也是个神器,关于他的介绍我不多说了,他的原理大概是:在当前可视窗口中,寻找与你截图相同的区域,然后操作该区域的中心点坐标。说下他的安装和用法。
1.安装
一般的安装教程网上有(https://launchpad.net/sikuli/+download这上面有全部的sikuli包信息)我的补充如下:
第一、新的下载地址为: Sikuli-X-1.0rc3 (r905)-win32.exe 。这个应用只有32位的,在32位系统上安装运行应该都没有问题(需要32位jre6之前的环境)。
第二、如果你对这个较为熟悉不需要IDE,你可以仅仅下载 Sikuli-X-1.0rc3 (r905)-win32.zip
第三、如果你非要在64位系统上安装sikuli的IDE,直接运行 Sikuli-X-1.0rc3 (r905)-win32.exe无视弹出的错误信息,不过终要运行在32位的jre6环境下。
对于32位系统的要注意jre好是在jre6(包括)之前的,免得可能会出现闪退的情况。对于64位系统的要保证其运行在32位的jre6下!可能有的同学不高兴了,我这已经搭建好了java环境,难不成要卸载了,重新装个32位的开发环境?答案是否定的。我们系统上可以运行多个版本的java环境。我们要做的只是保证其运行环境是32位的jre6可以了。为了避免你在oracel官网上对jre6进行寻找,我直接给出连接:http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase6-419409.html#jre-6u35-oth-JPR这个是jre6第35次编译的,注意的是:你仅仅需要下载运行环境,不需要下载开发环境。也不需要重新配置环境变量之类的操作,你需要的仅仅是更改安装目录下的Sikuli-IDE-w.bat这个dos脚本,将其中JAVA_EXE指向你新安装的32位jre6的安装目录。
说了这么多你应该明白了环境搭建方面的问题,当然如果有任何问题,你可以留言!下面说说这个脚本的编写,首先我们说说java环境下如何用这个脚本来操作flash;再看看如何在python中如何利用sikuli操作flash。在java中你需要干三件事:
1.将sikuli安装目录下的libs文件夹放在系统的环境变量中。
2.将eclipse的运行环境设置为32位jre。(不一定jre6只要32位jre行。上文sikuli IDE需要jre6的原因是这个IDE应该是在jdk6下开发的,而我们这里只是在eclipse运行sikuli-script.jar包中的相关方法)。
3.引入sikuli-script.jar包
简单的java测试代码如下:
/**
*
*/
/**
* @author PF-211X3
*
*/
package com;
import org.sikuli.script.*;
public class STest {
public static void main(String[] args) throws FindFailed, InterruptedException {
Screen s = new Screen();
String imgpath = "D:/img/";
s.wait(imgpath+"firfox.png", 5);
s.doubleClick(imgpath+"firfox.png");
System.out.println("end");
}
}
这个firfox.png是我们用任何截图工具截取桌面上firefox快捷图标的照片。上面的操作可以点击桌面上的firefox快捷图标打开火狐浏览器了。是不是很神奇!!所以我上文说了其实不需要安装sikuli的IDE。只需要sikuli-script.jar包与libs文件下的内容即可,相关的函数的用法你完全可以猜出来不行看看文档介绍!当然你想安装个IDE玩玩也是可以的~~
对于1没问题吧,添加环境变量大家都会。对于只会python完全没有接触过java的同事我给出2,3的步骤,java同学跳过!(我的pc是64位的,且我也已经下载好了32位的jre6的环境。)
如何将eclipse以32位的jre6运行该工程?
一、打开eclipse菜单window-》preferences弹出框,在左边的树形图找到java选项点开后选择Installed JRES在右边的选择框中选择Add添加我们32位jre我的截图如下:
上图大箭头部分是我们新安装的32位jre路径,我们选择改jre并点击Apply。