Greasy Fork镜像 还支持 简体中文。

自动提取政和验证码

接着奏乐接着舞 Find an img with src containing "api-uaa/v1/validate/code", get Base64, and send it for captcha code

目前為 2024-12-15 提交的版本,檢視 最新版本

// ==UserScript==
// @name         自动提取政和验证码
// @namespace    http://tampermonkey.net/
// @version      1.2
// @description  接着奏乐接着舞 Find an img with src containing "api-uaa/v1/validate/code", get Base64, and send it for captcha code
// @match        *://*/*
// @match        *://*/*
// @require      http://libs.baidu.com/jquery/2.0.0/jquery.min.js
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_xmlhttpRequest
// ==/UserScript==

// 处理图片验证码
function processImageCaptcha(imgElement) {
    if (!imgElement || !imgElement.src) return;
    // 打印图片信息
    console.log('识别图像验证码:', imgElement.src);
    // 将图片转换为 Base64 编码
    getBase64Code(imgElement).then(base64 => {
        // 这里可以调用识别 API 来处理 Base64 编码的图片
        console.log('图片Base64编码:', base64);
        // 发送 Base64 编码给服务器进行识别
        sendImageForOCR(imgElement, base64);
    }).catch(error => {
        console.error('图片转换失败:', error);
    });
}

// 获取图片的 Base64 编码
function getBase64Code(element) {
    // 设置跨域
    element.crossOrigin = 'Anonymous';
    return new Promise((resolve, reject) => {
        // 确保图片加载完成
        if (element.complete) {
            // 如果图片已经加载完,直接获取宽高
            resolve(getImageBase64(element));
        } else {
            element.onload = function () {
                resolve(getImageBase64(element));
            };
            element.onerror = function () {
                reject('图片加载失败');
            };
        }
    });
}

// 获取图片的 Base64 编码
function getImageBase64(element) {
    // 创建一个 canvas 元素
    const canvas = document.createElement('canvas');
    const context = canvas.getContext('2d');
    // 确保 canvas 的尺寸与图片相同
    canvas.width = element.naturalWidth;
    canvas.height = element.naturalHeight;
    console.log("验证码宽高:", element.naturalWidth, element.naturalHeight);
    // 将图片绘制到 canvas 上
    context.drawImage(element, 0, 0, element.naturalWidth, element.naturalHeight);
    // 获取图片的 Base64 编码
    return canvas.toDataURL('image/png');
}


// 发送图片到服务器进行 OCR 识别
function sendImageForOCR(imgElement, base64) {
    console.log("准备发送图片进行识别,图片 URL:", imgElement.src);
    console.log("Base64 编码:", base64);
    try {
        const formData = new FormData();
        formData.append("image", base64);
        GM_xmlhttpRequest({
            method: "POST", url: "https://ocr.xiaojingjing.top:8443/ocr", headers: {
                "accept": "application/json", "User-Agent": navigator.userAgent
            }, data: formData, onload: function (response) {
                const jsonResponse = JSON.parse(response.responseText);
                // 检查 code 是否为 200
                if (jsonResponse.code === 200) {
                    const inputElement = findClosestInput(imgElement);
                    if (inputElement) {
                        // 关闭输入框的验证
                        disableInputValidation(inputElement);
                        // 使用识别结果填充
                        inputElement.value = jsonResponse.data;
                        // 手动触发 input 事件,以便页面检测到输入的变化
                        const event = new Event('input', {bubbles: true});
                        inputElement.dispatchEvent(event);
                        // 如果还有其他事件检测输入,可以一并触发
                        const changeEvent = new Event('change', {bubbles: true});
                        inputElement.dispatchEvent(changeEvent);
                        console.log('验证码已填充至输入框:', jsonResponse.data);
                    } else {
                        console.log('未查询到输入框!');
                    }
                } else {
                    console.error('识别错误!:', jsonResponse.message);
                }
            }, onerror: function (error) {
                console.error('识别错误:', error);
            }
        });
    } catch (error) {
        console.error("识别异常:", error);
    }
}

// 禁用输入框的验证
function disableInputValidation(inputElement) {
    inputElement.removeAttribute('required');
    inputElement.removeAttribute('minlength');
    inputElement.removeAttribute('maxlength');
    inputElement.removeAttribute('pattern');
    // 移除错误提示标题
    inputElement.removeAttribute('title');
    // 如果输入框是属于一个表单,禁用整个表单的验证
    const form = inputElement.closest('form');
    if (form) {
        // 禁用表单验证
        form.setAttribute('novalidate', 'true');
    }
}

// 给图片添加左键点击事件
function addImageClickListener(imgElement) {
    if (!imgElement) return;
    // 给图片添加左键点击事件
    imgElement.addEventListener('click', function (e) {
        // 确保是左键点击
        if (e.button === 0) {
            // 左键点击
            console.log('点击了图片:', imgElement.src);
            processImageCaptcha(imgElement);
        }
    });
}

// 定义从 img 元素开始逐级向上查找最近的 input 元素的函数
function findClosestInput(element) {
    while (element) {
        element = element.parentElement;
        if (!element) break;
        const inputs = element.getElementsByTagName('input');
        if (inputs.length > 0) {
            // 返回找到的最后一个 input 元素
            return inputs[inputs.length - 1];
        }
    }
    return null;
}

// 检查页面上的验证码图像,并触发识别
function checkForCaptchaImages() {
    // 选择所有图片验证码元素
    $("canvas,img,input[type='image']").each(function () {
        // 确保是可见的图片,并且没有处理过
        const imgElement = this;
        if ($(imgElement).is(":visible") && !$(imgElement).data('processed')) {
            const imgSrc = imgElement.src;
            // 只处理包含 'api-uaa/v1/validate/code' 的图片
            if (imgSrc && imgSrc.includes('api-uaa/v1/validate/code')) {
                // 标记为已处理
                $(imgElement).data('processed', true);
                // 给图片添加左键点击事件
                addImageClickListener(imgElement);
                // 进行识别
                processImageCaptcha(imgElement);
            }
        }
    });
}


// 监听图片的变化,确保图像更新后重新触发识别
function observeImageChanges() {
    const observer = new MutationObserver(() => {
        checkForCaptchaImages();
    });
    // 监听 img 和 canvas 元素的变化
    observer.observe(document.body, {
        childList: true, subtree: true,
    });
}

// 开始监听图像变化
observeImageChanges();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址