最近在看python的爬虫框架(scrapy),一个词归纳就是:"酸爽"!等把selenium自动化版块讲完后,打算写一写关于scrapy相关的知识,打算从源码角度解析下scrapy这个框架。个人想法是它不只仅是用来爬网页的,更重要的是如何检测一个网站全部页面的健康性...回到正题,我想讲讲这个话题的原由是同事在自动化过程当中遇到了flash的点击操做,查阅网上的相关资料也得不到有效解决。今天我想一想谈谈这个flash的自动化操做问题!!html
随着页面作的愈来愈炫酷,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。java
对于一些IT基础比较薄弱的同窗来讲,始终不知道如何按照网上的步骤来进行下去,这里我对这个方案作个简单的解释以下:python
1.这个是须要原flash工程的,不是你获得的一个简单的swf文件就能从新编译的。简单的说就是找大家开发吧,让他把SeleniumFlexAPI.swc加入到被操做Flash(Flex)的工程文件的Build库中,从新Build Flash,而后从新发布到web上。这样你对这个新的flash可能用js进行操做了。web
2.SeleniumFlexAPI.swc这个文件以及很久很久没更新了...不知道是否对如今的flash可否操做有效,因此我在1中用了可能。windows
3.我总以为这个方法有点脱裤子放屁的感受,既然找开发帮你引入SeleniumFlexAPI.swc这个文件,还不如给你直接开放js接口,不是更好? 浏览器
吐槽了网上的方法,来讲说站在一个测试者角度的解决方案!oracle
1、利用AutoIt框架
从某种意义上来讲,我有点对这个工具产生依赖。当我在自动化过程当中绝望的时候,我就会第一时间想到它,而它也每每能带给我惊喜,就像上篇用fiddler录制接口同样(其实还有不少..)!来讲说我用这个工具来操做flash。我所操做的Flash图片以下:eclipse
这个Flash是有动画效果的,通过一段动画后出现上面图片的效果。个人任务就是点击上面图片中的小鼠标。下面贴出来AutoIt的脚本(最终转换成exe程序,在控制台中执行):
scrapy
#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也能够模拟其余咱们人为的操做,好比在输入框中输入、双击某个按钮等...注意的是,对于非标准控件你要尽量的保证相对坐标计算的准确性!
2、利用Sikuli
这个工具也是个神器,关于他的介绍我很少说了,他的原理大概就是:在当前可视窗口中,寻找与你截图相同的区域,而后操做该区域的中心点坐标。说下他的安装和用法。
1.安装
通常的安装教程网上有(https://launchpad.net/sikuli/+download这上面有所有的sikuli包信息)个人补充以下:
第1、最新的下载地址为: Sikuli-X-1.0rc3 (r905)-win32.exe 。这个应用只有32位的,在32位系统上安装运行应该都没有问题(须要32位jre6以前的环境)。
第2、若是你对这个较为熟悉不须要IDE,你能够仅仅下载 Sikuli-X-1.0rc3 (r905)-win32.zip
第3、若是你非要在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运行该工程?
1、打开eclipse菜单window-》preferences弹出框,在左边的树形图找到java选项点开后选择Installed JRES在右边的选择框中选择Add添加咱们32位jre个人截图以下:
上图大箭头部分是咱们新安装的32位jre路径,咱们选择改jre并点击Apply。
2、右键点击工程选择Build Path下的子菜单项Add Libraies...添加咱们选择的jre
选择咱们JRE System library-next->Workspace default JRE(jire6)点击Finish。
3.考虑运行的兼容性(不一样版本的jdk与jre配合须要此配置,相同版本的不须要),右击该工程选择菜单项Project->Properties。在弹出框中作一下配置:
如何添加外部包?
选中该工程右键点击该工程选择Build Path->Add External Archives...后导入本地目录下的sikuli-script.jar便可
上面咱们从sikuli角度来操做flash。总结下这种解决方案遇到的坑和注意点。
1.32系统上sikuli的环境搭建是问题不大的,除了sikuli ide的运行环境须要配置成jre6。64位系统上有点坑。上文中我也较详细的说明了ide的配置以及如何在eclipse中运行sikuli脚本,我相信你确定能运行起来。
2.注意点:sikuli对咱们截图的匹配查找是在咱们当前可视范围内的。这句话怎么理解呢?好比上文中我在桌面上截了一个firefox快捷图标的图片,当运行到点击这个快捷图标时,忽然弹出了一段小广告挡住了这个快捷图标,那么咱们的sikuli是找不到该图片的。个人解决办法是在运行sikuli脚本以前,最好先运行下AutoIt的一个小脚本,就是上文中咱们频繁使用到的WinActivate($hWnd)函数,能够确保某个窗口控件是可视的。
说到这来java部分也就这样了,可是本篇尚未结束,由于咱们尚未讲python中如何使用sikuli-script.jar这个包!
sikuli-script.jar是java下的包,python使用java的包最早想到的就是jpython。可是就为了操做个flash把python解析器设置为jpython我认为没人能接受。那么有一种神器能够链接python与java还能保证你的运行环境是cpython的,那这个包就是jpype。
对于32位系统,安装这个是最简单的你能够下载jpype.exe程序直接安装。jpype.exe暂时是没有64位,咱们选择安装包安装。路径为:https://pypi.python.org/pypi/JPype1。咱们下载后运行python setup.py install。发现多是有问题的,缘由是在windows平台上没法安装python c extension的扩展包,咱们下载专用的编译器Microsoft Visual C++ Compiler for Python 2.7就行了下载地址:https://www.microsoft.com/en-us/download/details.aspx?id=44266。
对于jpype的使用也是很是简单的,对于32位系统操做sikuli-script.jar这个包太简单就几行代码:
#coding=utf-8
import jpype
jvmPath = jpype.getDefaultJVMPath()
jpype.startJVM(jvmPath,"-ea",r"-Djava.class.path=D:\\tutorial\\tutorial\spiders\sikuli-script.jar")#jvmPath为jvm.dll的路径能够人为指定并指定外部包的加载路径
JDClass =jpype.JClass("org.sikuli.script.Screen")
s=JDClass()
imgpath = "D:/img/"
s.wait(imgpath + "firfox.png", 5)
s.doubleClick(imgpath + "firfox.png");
jpype.shutdownJVM()
这段代码与咱们上文的java代码意义是同样。为何说对于32位是没有问题的,难道64位python解析器没法这样用吗?
首先,并非说64位解析器没法经过jpype来启动一个虚拟机,可是问题是咱们只能启动一个64位的jvm。可是咱们上文说了sikuli-script.jar这个包没法在64位的jre中运行的,咱们尝试经过手动给出32位jre下面jvm.dll的路径来启用JVM进而运行sikuli-script.jar这个包。个人尝试代码:
#coding=utf-8
import jpype
jpype.startJVM(r"C:\Program Files (x86)\Java\jre6\bin\client\jvm.dll","-ea",r"-Djava.class.path=D:\\tutorial\\tutorial\spiders\sikuli-script.jar")#jvmPath为32位jre的jvm.dll路径
JDClass =jpype.JClass("org.sikuli.script.Screen")
s=JDClass()
imgpath = "D:/img/"
s.wait(imgpath + "firfox.png", 5)
s.doubleClick(imgpath + "firfox.png");
jpype.shutdownJVM()
发现是没法启动jvm的,缘由可能很简单咱们在64位的python解析器上运行32位jvm.dll多少有点问题。那么咱们在64位上如何使用sikuli呢?没办法我能想到的就只有曲线救国了...对的,就是用python调用控制台来运eclipse里的工程。个人作法以下:
1.导出该工程为jar包。
步骤:选择该工程选择菜单的File->Export,选择JAR File,而后一路向西导出到某个路径下,我直接放桌面了。
2.修改改jar包中的MANIFEST.MF文件。
步骤1、修改改jar包后缀名为zip。好比将abc.jar变成abc.zip
步骤2、修改里面的META-INF中的MANIFEST.MF文件,添加Main-Class: com.STest
步骤3、保存后修改abc.zip为abc.jar
3.修改完jar包后咱们直接编写运行这个jar的dos脚本以下:
cmd命令:"C:\Program Files (x86)\Java\jre6\\bin\java" -Djava.ext.dirs=C:\lib -jar C:\Users\PF-211X3\Desktop\\abc.jar
这个简单的说明吧!
1、C:\Program Files (x86)\Java\jre6\\bin\java是咱们32位jre的路径下java命令
2、-Djava.ext.dirs命令参数如同jpype中的参数-Djava.class.path同样为咱们外部引用包,我这里是把sikuli-script.jar这个包放在C盘的lib下的
3、-jar参数后面跟的是咱们刚修改过的jar包
以上只是个例子,具体路径配置按本身我的状况界定。
咱们发如今个在cmd中是能正常运行的,那么咱们如何在python中运行这个我相信,不须要我多说了吧
import os cmd="\"C:\Program Files (x86)\Java\jre6\\bin\java\" -Djava.ext.dirs=C:\lib -jar C:\Users\PF-211X3\Desktop\\abc.jar" os.popen(cmd)
好吧,咱们总算经过曲线救国的方式使得python在64系统上用sikuli操做flash。在32位上仍是用jpype吧!
最后咱们作个简单的总结吧:
咱们上面使用Autoit与sikuli方法操做flash,2种方法各有特点吧!固然可能还有其余更好更方便的方法操做flash,但愿知道的大神们能写出来~~