300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 使用Java+Puppeteer+OpenCV 过腾讯防水墙滑动验证码

使用Java+Puppeteer+OpenCV 过腾讯防水墙滑动验证码

时间:2020-09-01 10:45:21

相关推荐

使用Java+Puppeteer+OpenCV 过腾讯防水墙滑动验证码

借鉴 /weixin_44549063/article/details/112192478 这个博客,有些直接拿来用了

效果图:

上代码:

import com.ruiyun.jvppeteer.core.Puppeteer;import com.ruiyun.jvppeteer.core.browser.Browser;import com.ruiyun.jvppeteer.core.page.Frame;import com.ruiyun.jvppeteer.core.page.Page;import com.ruiyun.jvppeteer.options.*;import mons.io.FileUtils;import org.opencv.core.*;import org.opencv.imgcodecs.Imgcodecs;import org.opencv.imgproc.Imgproc;import javax.imageio.ImageIO;import java.awt.image.BufferedImage;import java.io.File;import java.io.IOException;import .URL;import java.util.ArrayList;import java.util.List;import java.util.Random;import java.util.concurrent.ExecutionException;import java.util.concurrent.atomic.AtomicReference;public class Captcha {public static void main(String[] args) throws InterruptedException, ExecutionException, IOException {new Captcha().start();}public void start() throws IOException, InterruptedException, ExecutionException {Browser browser = Puppeteer.launch(false);Page page = browser.newPage();page.goTo("https://open./online.html");page.waitFor("2000");page.evaluate("window.scrollTo(0,300)");page.$("button[id=code]").click();page.waitFor("2000");verifyCaptcha(page);}/*** @param page 谷歌窗口页面page* @return*/public void verifyCaptcha(Page page) {List<Frame> frameList = page.frames();AtomicReference<Frame> frame = new AtomicReference<>();frameList.forEach(f -> {if (f.url().contains("cap_union_new_show")) {frame.set(f);}});String bgUrl = frame.get().$eval("img[id=slideBg]", "j => j.src",new ArrayList<>()).toString();//大图 urlString sUrl = frame.get().$eval("img[id=slideBlock]", "j => j.src",new ArrayList<>()).toString();//小滑块 图片urlString styleStr = frame.get().$eval("img[id=slideBlock]", "e => e.outerHTML",new ArrayList<>()).toString().replaceAll("<img.*style=\"", "").replace(";\">", "");String widthStr;String topStr;int top;//背景图与原图比例double radio;widthStr = styleStr.substring(styleStr.indexOf("width: ") + 7, styleStr.indexOf("px; top"));topStr = styleStr.substring(styleStr.indexOf("top: ") + 5, styleStr.indexOf("px; left"));radio = 136 / Double.parseDouble(widthStr);top = (int) (Integer.parseInt(topStr) * radio);//计算滑动距离int distance = (int) Double.parseDouble(getTencentDistance(bgUrl, sUrl, top, radio));//移动滑块move(page, distance, frame.get());}}/*** @param distance 需要移动的距离* @return*/public List<Integer> getMoveTrack(int distance) {// 移动轨迹List<Integer> track = new ArrayList<>();Random random = new Random();// 已经移动的距离int current = 0;// 减速阈值int mid = distance * 4 / 5;int a;// 每次循环移动的距离int move = 0;while (true) {a = random.nextInt(150);if (current <= mid) {move += a;} else {move -= a;}if ((current + move) < distance) {track.add(move);} else {track.add(distance - current);break;}current += move;}return track;}public String getTencentDistance(String bUrl, String sUrl, int top, Double radio) {System.load("E:\\opencv\\opencv\\build\\java\\x64\\opencv_java454.dll");File bFile = new File("E:\\tcaptcha\\qq_b.jpg");File sFile = new File("E:\\tcaptcha\\qq_s.jpg");BufferedImage bgBI;BufferedImage sBI;try {FileUtils.copyURLToFile(new URL(bUrl), bFile);FileUtils.copyURLToFile(new URL(sUrl), sFile);bgBI = ImageIO.read(bFile);sBI = ImageIO.read(sFile);// 裁剪 x坐标从360开始是自定义的,原图尺寸w:680 h:390 分析得知一般缺块出现位置为中间位置偏右,即680/2=340偏右,取360;减370,截取的位置原图往左10pxbgBI = bgBI.getSubimage(360, top, bgBI.getWidth() - 370, sBI.getHeight());ImageIO.write(bgBI, "png", bFile);Mat s_mat = Imgcodecs.imread(sFile.getPath());Mat b_mat = Imgcodecs.imread(bFile.getPath());// 转灰度图像Mat s_newMat = new Mat();Imgproc.cvtColor(s_mat, s_newMat, Imgproc.COLOR_BGR2GRAY);// 二值化图像binaryzation(s_newMat);Imgcodecs.imwrite(sFile.getPath(), s_newMat);int result_rows = b_mat.rows() - s_mat.rows() + 1;int result_cols = b_mat.cols() - s_mat.cols() + 1;Mat g_result = new Mat(result_rows, result_cols, CvType.CV_32FC1);Imgproc.matchTemplate(b_mat, s_mat, g_result, Imgproc.TM_SQDIFF); // 归一化平方差匹配法// 归一化相关匹配法Core.normalize(g_result, g_result, 0, 1, Core.NORM_MINMAX, -1, new Mat());Core.MinMaxLocResult mmlr = Core.minMaxLoc(g_result);Point matchLocation = mmlr.maxLoc; // 此处使用maxLoc还是minLoc取决于使用的匹配算法Imgproc.rectangle(b_mat, matchLocation,new Point(matchLocation.x + s_mat.cols(), matchLocation.y + s_mat.rows()), new Scalar(0, 0, 0, 0));//减23*radio: 23是小滑块左侧距离图片边缘有一段距离为23px,固定不变;radio是浏览器的背景图与背景原图的比例return "" + (int) ((matchLocation.x + s_mat.cols() + 360 - sBI.getWidth() - 23 * radio) / radio);} catch (Exception e) {e.printStackTrace();return null;}}/*** @param mat 二值化图像*/public void binaryzation(Mat mat) {int BLACK = 0;int WHITE = 255;int ucThre = 0, ucThre_new = 127;int nBack_count, nData_count;int nBack_sum, nData_sum;int nValue;int i, j;int width = mat.width(), height = mat.height();// 寻找最佳的阙值while (ucThre != ucThre_new) {nBack_sum = nData_sum = 0;nBack_count = nData_count = 0;for (j = 0; j < height; ++j) {for (i = 0; i < width; i++) {nValue = (int) mat.get(j, i)[0];if (nValue > ucThre_new) {nBack_sum += nValue;nBack_count++;} else {nData_sum += nValue;nData_count++;}}}nBack_sum = nBack_sum / nBack_count;nData_sum = nData_sum / nData_count;ucThre = ucThre_new;ucThre_new = (nBack_sum + nData_sum) / 2;}// 二值化处理int nBlack = 0;int nWhite = 0;for (j = 0; j < height; ++j) {for (i = 0; i < width; ++i) {nValue = (int) mat.get(j, i)[0];if (nValue > ucThre_new) {mat.put(j, i, WHITE);nWhite++;} else {mat.put(j, i, BLACK);nBlack++;}}}// 确保白底黑字if (nBlack > nWhite) {for (j = 0; j < height; ++j) {for (i = 0; i < width; ++i) {nValue = (int) (mat.get(j, i)[0]);if (nValue == 0) {mat.put(j, i, WHITE);} else {mat.put(j, i, BLACK);}}}}}public void move(Page page, int distance, Frame frame) {int randomTime = 0;if (distance > 90) {randomTime = 80;} else if (distance > 80) {randomTime = 50;}double d = distance + 30;List<Integer> track = getMoveTrack((int) d);try {ClickOptions clickOptions = new ClickOptions();clickOptions.setButton("left");Clip clip = frame.$("div[id=tcaptcha_drag_button]").boundingBox();frame.$("div[id=tcaptcha_drag_button]").click(clickOptions, true);double moveX = clip.getX();for (Integer integer : track) {moveX += integer;page.mouse().move(moveX, clip.getY(), 20);Thread.sleep(new Random().nextInt(100) + randomTime);}Thread.sleep(1000);} catch (Exception e) {e.printStackTrace();} finally {page.mouse().up();}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。