selenium 过网页版抖音滑块,滑块未测试, java 测试ok。失业好久了,java 爬虫没前途

 

打开小姐姐个人主页  https://www.douyin.com/user/MS4wLjABAAAAcHcG7GZFPOBmv0E4OGWn-KR4d-xxJ6VtsNLBRcNcb7Xtg5h3Vv_otohQsjBsxfpb 就会出现验证码

 

 

将 大的 div 保存为图片,即 class 为 captcha_verify_container 的 div 保存为图片, java 代码 

 // 查找目标 <div> 元素 --wrapper
        WebElement divElement = driver.findElement(By.className("captcha_verify_container"));
        WebElement imageElement = driver.findElement(By.id("captcha-verify-image"));
        if(divElement == null || imageElement == null) {
            return false;
        }

        // 创建 Actions 对象
        Actions actions = new Actions(driver);

        // 获取元素的位置和大小
        Rectangle rect = divElement.getRect();

        String res = devTools.send(Page.captureScreenshot(
                Optional.of(Page.CaptureScreenshotFormat.PNG),
                Optional.empty(),
                Optional.of(new Viewport((double)rect.getX(), (double)rect.getY(), (double)rect.getWidth(), (double)rect.getHeight(), 1.0)),
                Optional.empty(),
                Optional.empty(),
                Optional.empty()
        ));




        // 保存截图为文件
        byte[] screenshotData = Base64.getDecoder().decode(res);
        

            Path screenshotPath = Paths.get(imagePath);
            Files.write(screenshotPath, screenshotData, StandardOpenOption.CREATE);
            System.out.println("Screenshot saved: " + screenshotPath.toAbsolutePath());

 

原因,图片中的  "依次点击 喳 双 团" 是一张图片 , 不是 文字,是文字会方便很多,如果是文字,图片就直接从 class 为 ”captcha_verify_img--wrapper“ 的 div 会方便很多。

现在不是文字,另外的方案,从 class 为 ”captcha_verify_bar“ 获取图片,再对接第三方OCR识别出 ”喳 双 团“, 再从 class 为 ”captcha_verify_img--wrapper“ 获取图片

现在方案,直接将 class 为 captcha_verify_container 的 div 保存为图片,假设为 图片 1

 仅仅将 class 为 "captcha_verify_img--wrapper" 保存为图片,假设为 图片2

图片1是 475 * 435, 图片2 是 425 * 265

经过分析,画出如下草图(逆时针旋转90°)

 

 

将 图片1 接入打码平台,假设获取到3个坐标点  (x1,y1) (x2,y2) (x3,y3)

actions.moveToElement(divElement, x1,y1).click().perform(); 这样肯定是不能通过的 (这里的 divElement 本来我是打算用 imageElement ,没想到测试通过了 )

 

 

 

如图(上面说的图2一样),debug 的时候,发现 红色1的坐标的 (0,0),   红色2的坐标是 (-169,-105), 其实应该是 (-170, -106), 整个长宽就是 170*2=340,106*2=212,

上面说到,图片2的长宽是 425*265,缩放比例是  425 / 340=1.25  265/212=1.25

所以,打码获取到的 x 和 y 的坐标,需要重新计算

    public static int rex(int x) {
        double d = x;
        d = d - 25 - 212.5;
        d = d / 1.25;
        return new BigDecimal(String.valueOf(d)).intValue();
    }

    public static int rey(int y) {
        double d = y;
        d = d - 85 - 132.5;
        d = d / 1.25;
        return new BigDecimal(String.valueOf(d)).intValue();
    }

首先 x 要减去 25,y 要减去 85,看那个草图

x 再要减去 212.5,整个 长度是 425 , 中间的坐标点是 (0,0), 425 / 2 = 212.5, y 再减去  132.5

再等比缩放 1.25 即可。

整个代码 随便看看

 

import com.alibaba.fastjson.JSONObject;
import com.common.util.CommonUtils;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.v113.page.Page;
import org.openqa.selenium.devtools.v113.page.model.Viewport;
import org.openqa.selenium.interactions.Actions;

import java.io.File;
import java.io.FileInputStream;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Base64;
import java.util.Optional;

public class TestDevTools2 {



    static String imagePath = "C:\\particularElementScreenshot.PNG";
    static String chromePath = "D:\\java_project\\chromedriver.exe";


    public static void main(String[] args) {


        System.setProperty("webdriver.chrome.driver", chromePath);
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--disable-blink-features=AutomationControlled");
        options.addArguments("disable-infobars");
        options.addArguments("start-maximized");
        options.addArguments("ignore-certificate-errors");
        options.addArguments("--remote-allow-origins=*");
        options.setExperimentalOption("excludeSwitches", new String[]{"enable-automation"});
        options.setExperimentalOption("useAutomationExtension", false);

        // Initialize browser
        ChromeDriver driver = null;
        DevTools devTools = null;
        try {
            driver = new ChromeDriver(options);

            // 使用 DevTools API 进行截图
            devTools = driver.getDevTools();
            devTools.createSession();
            // 增加等待时间
            //driver.manage().timeouts().setScriptTimeout(Duration.ofSeconds(30));

            driver.manage().window().setSize(new Dimension(627, 537));
          //  driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);

            // 导航到包含目标 <div> 元素的页面
            driver.get("https://www.douyin.com/user/MS4wLjABAAAAcHcG7GZFPOBmv0E4OGWn-KR4d-xxJ6VtsNLBRcNcb7Xtg5h3Vv_otohQsjBsxfpb");



            needCheck(driver, devTools);

            //
            System.out.println("获取数据");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(driver != null) {
                driver.quit();
            }
        }
    }


    public static boolean needCheck(ChromeDriver driver, DevTools devTools) {

        CommonUtils.sleepMillisecond(10000);

        // 查找目标 <div> 元素 --wrapper
        WebElement divElement = driver.findElement(By.className("captcha_verify_container"));
        WebElement imageElement = driver.findElement(By.id("captcha-verify-image"));
        if(divElement == null || imageElement == null) {
            return false;
        }

        // 创建 Actions 对象
        Actions actions = new Actions(driver);

        //actions.moveToElement(imageElement, 0, 0).click().perform();;

        // 获取元素的位置和大小
        Rectangle rect = divElement.getRect();

        String res = devTools.send(Page.captureScreenshot(
                Optional.of(Page.CaptureScreenshotFormat.PNG),
                Optional.empty(),
                Optional.of(new Viewport((double)rect.getX(), (double)rect.getY(), (double)rect.getWidth(), (double)rect.getHeight(), 1.0)),
                Optional.empty(),
                Optional.empty(),
                Optional.empty()
        ));




        // 保存截图为文件
        byte[] screenshotData = Base64.getDecoder().decode(res);
        try {
            Path screenshotPath = Paths.get(imagePath);
            Files.write(screenshotPath, screenshotData, StandardOpenOption.CREATE);
            System.out.println("Screenshot saved: " + screenshotPath.toAbsolutePath());

            File file = new File(imagePath);
            String resultString= Jsoup.connect("http://api.ttshitu.com/predict")
                    .data("username", "---------------------------------")
                    .data("password", "---------------------------------")
                    .data("typeid", "27")
                    .data("remark", "")
                    .data("image", file.getName(), new FileInputStream(file)).ignoreContentType(true).timeout(120000).post().text();


            // {"code":"0","data":{"result":"173,190|362,177|133,295","id":"UsWi7VEyRZy7SvvLnJ6HjQ"},"success":true,"message":"success"}
            JSONObject jsonObject = JSONObject.parseObject(resultString);
            System.out.println(jsonObject);

            String result = Optional.ofNullable(jsonObject).map(t -> t.getJSONObject("data")).map(t -> t.getString("result")).orElse(null);
            System.out.println(result);

            if(StringUtils.isBlank(result)) {
                return false;
            }

            String[] strs = result.split("\\|");
            if(strs == null || strs.length < 1) {
                return false;
            }

           

             for(String s : strs) {
                String[] ss = s.trim().split(",");
                if(ss != null && ss.length == 2){
                    int x = Integer.parseInt(ss[0].trim());
                    int y = Integer.parseInt(ss[1].trim());
                    System.out.println(s + " , " + x  + ", " + y + " -> " + rex(x) + ", " + rey(y));
                    // 这里打算使用 imageElement ,测试的时候居然用 divElement 通过了,
                    actions.moveToElement(divElement, rex(x), rey(y)).click().perform();
                  
                     CommonUtils.sleepMillisecond(2000);
                }
            }

            //


            // actions.moveByOffset(410, 395).click().perform();
            divElement = driver.findElement(By.className("verify-captcha-submit-button"));
            if(divElement != null) {
                divElement.click();
            }
            CommonUtils.sleepMillisecond(5000);

            divElement = driver.findElement(By.className("captcha_verify_container"));
            if(driver != null) {
                return needCheck(driver, devTools);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

    public static int rex(int x) {
        double d = x;
        d = d - 25 - 212.5;
        d = d / 1.25;
        return new BigDecimal(String.valueOf(d)).intValue();
    }

    public static int rey(int y) {
        double d = y;
        d = d - 85 - 132.5;
        d = d / 1.25;
        return new BigDecimal(String.valueOf(d)).intValue();
    }
}


        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>4.9.1</version>
        </dependency>

        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-chrome-driver</artifactId>
            <version>4.9.1</version>
        </dependency>

        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-remote-driver</artifactId>
            <version>4.9.1</version>
        </dependency>

        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-devtools-v111</artifactId>
            <version>4.9.1</version>
        </dependency>

        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-api</artifactId>
            <version>4.9.1</version>
        </dependency>

 

===================== 经过测试,很完美 很专业 ================

将代码放到其他地方测试,没通过,发现 大图变成了 380 * 348, 小图成了 340 * 212,假设大图左上角的坐标是(0,0),小图左上角的坐标就是(20,68)

340 / 2 = 170, 212 / 2 = 106 所以 重新计算坐标

    public static int rex(int x) {
        double d = x;
        d = d - 20 - 170;
        d = d / 1;
        return new BigDecimal(String.valueOf(d)).intValue();
    }

    public static int rey(int y) {
        double d = y;
        d = d - 68 - 106;
        d = d / 1;
        return new BigDecimal(String.valueOf(d)).intValue();
    }

测试发现,上面除以 1.25, 这里除以1,不知道是不是与电脑分辨率有关。

    

 

 大致思路就是这样。

 

posted @ 2023-08-09 01:12 safetys 阅读(476) 评论(1) 推荐(0) 编辑
摘要: 如上4张图片,其中 2 3 是向左凸出来的。 图片处理,以上图2为例, 图片 -> 高斯模糊 -> 图片灰度化处理 -> 边缘检测 ,没有二值化处理。 最后的图片,在python下,显示的像素点 思路,统计每个 x 轴(因为我是检测图片是否向左凸出来)上,rgb 等于255的个数。假设图片是像左凸出 阅读全文
posted @ 2020-09-24 12:43 safetys 阅读(601) 评论(0) 推荐(0) 编辑
摘要: 谷歌验证码,好几个版本,此处只针对于V2版本。 1、去网站 https://2captcha.com 注册,获取API Key 。首次需要充值10美元。 2、https://2captcha.com/2captcha-api#solving_recaptchav2_new ,查看解决方案。 3、这里 阅读全文
posted @ 2020-01-13 15:18 safetys 阅读(2089) 评论(4) 推荐(0) 编辑
摘要: 个人站点最新文章提交到百度(java实现) 阅读全文
posted @ 2015-07-03 15:48 safetys 阅读(477) 评论(0) 推荐(0) 编辑
摘要: 文章是翻译的。谷歌Chrome浏览器突然不打开任何网页,无论是任何站点(如http://www.baidu.com), 还是Chrome浏览器的设置页面(chrome://settings/), 扩展页面 (chrome://extensions/) ,所有其他浏览器(如IE浏览器,Mozilla ... 阅读全文
posted @ 2014-09-08 09:18 safetys 阅读(38466) 评论(1) 推荐(3) 编辑
摘要: Httpclient 中常用的请求有2个,HttpPost 和 HttpGet,今天在对某个网站进行分析的时候,突然发现用到了 HttpDelete,并且传参 是 Json。1、一般 HttpPost 对传参 Json 的处理是:// 中文处理StringEntity se = new String... 阅读全文
posted @ 2014-06-16 01:07 safetys 阅读(16964) 评论(1) 推荐(0) 编辑
摘要: javascript md5 二次加密 和 java md5 二次加密结果不同 阅读全文
posted @ 2014-06-06 14:48 safetys 阅读(976) 评论(0) 推荐(0) 编辑
摘要: 说明:Quartz + Servlet, 参考国外著名站点的文章:http://stackoverflow.com/questions/12208309/need-to-set-the-quartz-cron-expression-dynamically 看域名,大家就知道了吧。1、简单编写一个 q... 阅读全文
posted @ 2014-05-20 22:58 safetys 阅读(8563) 评论(1) 推荐(1) 编辑
摘要: 碰到不会的技术问题,我还是先度娘。能中文看懂,为什么非要看英文呢。java 解析/读取 种子/bt/torrent 内容,这个度娘给的满意答案并不是很多。GG之后的搜索结果出现了stackoverflow这个网站,技术人员都懂的,基本有解决方案了,犹如黑暗里的萤火虫,早期度娘java问题的javaeye。有3种解决方案1、不适用第三方jar,可以看看http://blog.csdn.net/phinecos/article/details/4611924。 度娘给的基本都是这种解决方案。顺便鄙视下国内的某些程序员,转载别人的文章时,也不测试下,结果1传10,10传100,都是有bug的。2、使 阅读全文
posted @ 2013-07-11 14:12 safetys 阅读(13296) 评论(1) 推荐(1) 编辑
摘要: FFMPEG功能很强大,做视频必备的软件。大家可通过 http://ffmpeg.org/了解。Windows版本的软件,可通过 http://ffmpeg.zeranoe.com/builds/下载。因为有这个需求,通过 ffmpeg 获取视频第一帧图片,没办法,自己觉得比别人强的,就是会搜索,会google ^_^。Google一把,就有了结果。1、VideoInfo.java获取视频信息。读者可认真研究此方法。import java.io.*;import java.util.regex.Matcher;import java.util.regex.Pattern;/** * 获取视频的 阅读全文
posted @ 2012-10-19 15:04 safetys 阅读(10252) 评论(0) 推荐(0) 编辑
点击右上角即可分享
微信分享提示