Selenuim 解决最简单滑动验证码 java版
2021-03-03 04:28
标签:坐标 ide common 字节数组 验证 java form ace start 新年快乐! 先记录下写这篇随笔的初衷: 同一个项目组的测试组在推广写自动化用例,组长说用selenium写,底下的测试们只能照做喽。一群测试小伙伴们都没学过java,于是一个玩得来的测试同事经常来找我,问我java语法、selenium定位元素等等怎么写。 我也没学过selenium,不过懂点java语法。 他们碰到一个难题,自动化用例都阻塞在登陆页面了,开发、测试环境页面上有用到极验验证码,还好只是最简单的滑动验证码。这下自动化用例登陆都登不进去,全阻塞在那儿了。 用selenium的java版本写出来了,也算有点收获,毕竟靠自己亲手解决了一个难题。 坎坷经历:最开始看到这样一个滑动验证码,思路是验证会发送ajax请求,请求参数携带了一个加密的字符串w, 一开始还想着从geetest.js文件入手,我没有啥JavaScript专业的学习,研究了一天半天就放弃了。毕竟JS编码加混淆对我来说太难了。 后来换了个思路,把这两张图给他另存为到本地,然后通过比较像素点,找到缺口的横坐标。 想法是好的, 但是验证码用canvas画的,我没有用过canvas,但是看到验证码可以右键另存为到本地,于是我又去搜索selenium如何右键另存为图片(要使用autoit,好像有点困难,于是我放弃了),这下又折腾了一两天。 后来旁边的前端小伙伴告诉我canvas可以转为base64编码,于是我就试了一试,所幸我们的环境上是可行的。 回家后又在本地随意找了个网站试了试,可行的所以记录下来。如果没有硬性要求要用selenium,也没有严格的内网环境,完全可以使用python,github上有解决方案,或者使用别人开发好的接口,好像是收费的。我只是兴趣之余给我的测试小伙伴减少工作难题,毕竟人家老是来找我探讨。 效果图大约2M,文件有点大,页面加载可能有点慢。 将有缺口和没有缺口的验证码图片逐点比对,像素点差60以上,我们就认为这个点是缺块内的;找到第一个缺块点的X坐标,滑块移动到这就个位置了。 测试的时候发现滑块对上了,但是提示"怪物吃掉了",看接口响应是 forbidden,应该是运动轨迹被识别为自动的,所以禁止登陆。这个时候你完全可以写个自己的运动轨迹。先加速后匀速,或者匀速过去,超一点再倒回来。 方式可以有很多,实现目的就行。 测试类代码如下: 滑块验证码代码如下: 和测试小伙伴一起学习selenium使用过程中,也学到了一些知识。学习一些东西,有一些收获就要记录下来。虽然以后可能不怎么会用到这门技术。 以前我都不知道什么是xpath,我理解的xpath是定位扩展标记语言的方式,比如通过selenium定位元素:F12控制台还能这么用,右键直接可以复制元素的xpath,直接就能用了。 xpath几种定位方式: //元素名[@属性名="属性值"] //元素名[text()="文本内容"] //元素名/parent::父元素类型 //元素名/子元素名[下标从1开始] 以上就是我从xpath中学到的以及在日常中能常使用的。 转为字节数组之后就可以生成文件到本地。 Selenuim 解决最简单滑动验证码 java版 标签:坐标 ide common 字节数组 验证 java form ace start 原文地址:https://www.cnblogs.com/lvbinbin2yujie/p/14398744.html0 演示效果图
1 滑块验证码思路
1.1 像素点
1.2 移动轨迹
2 JAVA代码
2.1 java实现代码
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class AutoTests {
public static void main(String[] args) throws Exception {
try {
System.setProperty("webdriver.chrome.driver", "D:\\new_soft\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("https://www.geetest.com/Register");
driver.manage().window().maximize();
driver.findElement(By.xpath("//input[@placeholder=\"手机号码\"]")).sendKeys("11111111111");
driver.findElement(By.xpath("//div[text()=\"获取验证码\"]")).click();
//处理滑动验证码
SlideVerifyBlock.common(driver);
Thread.sleep(2000);
driver.quit();
} catch (Exception e) {
e.printStackTrace();
}
}
}
滑块验证码算出来的像素点距离减去8,是因为滑块距离图片最左边一般都是紧贴着的,我量了一下大约8,所以才减去这么多。moveWay1
和moveWay2
于2021/2/12测试时候是均可通过的。import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import sun.misc.BASE64Decoder;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class SlideVerifyBlock {
// 减少计算50
private static final int OFFSET = 50;
// 滑块和左边轴都有一定的距离, 误差范围内都可以接受
private static final int LEFT_GAP = 8;
//加速度
private static int a_speed = 150;
public static void common(WebDriver driver) throws Exception {
String bgClassName = "geetest_canvas_bg geetest_absolute",
bgFullClassName = "geetest_canvas_fullbg geetest_fade geetest_absolute";
String getImgBase64 = "return document.getElementsByClassName(\‘%s\‘)[0].toDataURL(‘image/png‘);";
//等待一下验证码加载出来
Thread.sleep(1000);
String bgImg = ((JavascriptExecutor) driver).executeScript(String.format(getImgBase64, bgClassName)).toString();
bgImg = bgImg.startsWith("data:image/png;base64,") ? bgImg.substring(22) : bgImg;
String bgFullImg = ((JavascriptExecutor) driver).executeScript(String.format(getImgBase64, bgFullClassName)).toString();
bgFullImg = bgFullImg.startsWith("data:image/png;base64,") ? bgFullImg.substring(22) : bgFullImg;
BASE64Decoder decoder = new BASE64Decoder();
byte[] bgBytes = decoder.decodeBuffer(bgImg);
byte[] bgFullBytes = decoder.decodeBuffer(bgFullImg);
generateFile(bgBytes, "C:\\Users\\Administrator\\Desktop\\笔记", "bg.png");
generateFile(bgFullBytes, "C:\\Users\\Administrator\\Desktop\\笔记", "bgfull.png");
InputStream inputStream = new ByteArrayInputStream(bgBytes);
InputStream inputStream2 = new ByteArrayInputStream(bgFullBytes);
BufferedImage bg = ImageIO.read(inputStream), fullBg = ImageIO.read(inputStream2);
;
int width = bg.getWidth(), height = bg.getHeight();
int[] tmp1 = new int[3], tmp2 = new int[3];
int gap = 0;
outer:
for (int i = OFFSET; i > 16) & 0xff;
tmp1[1] = (rgb1 >> 8) & 0xff;
tmp1[2] = rgb1 & 0xff;
tmp2[0] = (rgb2 >> 16) & 0xff;
tmp2[1] = (rgb2 >> 8) & 0xff;
tmp2[2] = rgb2 & 0xff;
if (Math.abs(tmp1[0] - tmp2[0]) doubles = moveManualiy(driver, gap - LEFT_GAP);
Double[] array = doubles.toArray(new Double[doubles.size()]);
double res = 0;
for (int i = 0; i moveManualiy(WebDriver driver, double distance) {
DecimalFormat df = new DecimalFormat("######0.00");
// 先加速移动 然后匀速移动 1/2*a*t0^2 + at0 * t1 = distance
double current = 0;
ArrayList
3 收获
3.1 xpath
优点:简单快捷
缺点:/html/body/div[3]/div[2]/div[6]/div/div[1]/div[1]/div/a/div[1]/div/canvas[2]
形如这种页面稍微变化下,就不能用了; 不利于阅读。
比如//div[@id="udesk_container"]
比如//p[text()="武汉极意网络科技有限公司"]
比如//p[text()=‘如果需要了解产品信息或售前服务欢迎联系我们‘]/parent::div
,用来定位到查找元素的父亲元素
比如//div[@class="geetest_panel_success geetest_success_animate"]/div[2]
,用来查找指定元素的子元素3.2 base64图片内容转为字节数组
BASE64Decoder decoder = new BASE64Decoder();
byte[] bgBytes = decoder.decodeBuffer(bgImg);
FileOutputStream stream = new FileOutputStream(fileDirector + File.separator + filename);
stream.write(data);
stream.flush();
stream.close();
上一篇:Java的标识符和关键字
文章标题:Selenuim 解决最简单滑动验证码 java版
文章链接:http://soscw.com/index.php/essay/59355.html