Greasy Fork is available in English.
自动解析网站验证码并填充
当前为
// ==UserScript==
// @name 自动解析验证码脚本
// @namespace http://tampermonkey.net/
// @version 1.0.0
// @description 自动解析网站验证码并填充
// @author shen chen
// @match *://*/*
// @grant GM_xmlhttpRequest
// @license MIT
// ==/UserScript==
const backUrl = "http://47.98.114.76:81/verification-code";
// 定义一个包含目标网站信息的列表
const siteList = [
{
url: "https://zkpt.zj.msa.gov.cn/#/login", // 目标网站URL
imageXpath: "//img[@alt='验证码']", // 验证码图片的XPath
valueXpath: "//input[@placeholder='图片验证码']" // 验证码输入框的XPath
},
{
url: "http://10.30.10.42:9080/user/login?redirect=%2F",
imageXpath: "//div[@class='ant-col ant-col-8']//img[1]",
valueXpath: "(//input[@class='ant-input ant-input-lg'])[3]"
},
{
url: "http://121.41.173.27:9080/user/login",
imageXpath: "//div[@class='ant-col ant-col-8']//img[1]",
valueXpath: "(//input[@class='ant-input ant-input-lg'])[3]"
},
// 可以添加更多网站配置
];
/**
* 根据XPath获取DOM元素
* @param {string} xpath - XPath表达式
* @returns {HTMLElement|null} - 匹配到的元素或null
*/
function getElementByXpath(xpath) {
const result = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
return result.singleNodeValue;
}
/**
* 将图片元素转换为Base64编码
* @param {HTMLImageElement} imageElement - 图片元素
* @param {function} callback - 回调函数,返回Base64字符串
*/
function getCaptchaImageAsBase64(img, callback) {
img.crossOrigin = 'Anonymous'; // 处理跨域问题
img.onload = function () {
const canvas = document.createElement('canvas');
canvas.width = 120;
canvas.height = 40;
// console.log('图片尺寸:', img.width, img.height)
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
// 获取Base64编码
const dataURL = canvas.toDataURL('image/png');
// console.log('Base64编码:',dataURL);
callback(dataURL);
};
img.onerror = function () {
console.error('图片加载失败');
callback(null);
};
}
/**
* 发送验证码图片到后端接口并填充解析结果
* @param {string} base64Image - 验证码图片的URL
* @param {string} valueXpath - 验证码输入框的XPath
*/
function sendCaptchaToBackend(base64Image, valueXpath) {
// console.log("发送验证码图片到后端接口:");
GM_xmlhttpRequest({
method: "POST",
url: backUrl,
headers: {
"Content-Type": "application/json"
},
data: JSON.stringify({image_base64: base64Image}),
onload: function (response) {
const data = JSON.parse(response.responseText);
if (data.captcha_value) {
// console.log("验证码解析成功:", data.captcha_value);
// 自动填写验证码到输入框
const captchaInput = getElementByXpath(valueXpath);
if (captchaInput) {
captchaInput.value = data.captcha_value;
// console.log("验证码已自动填写");
} else {
console.error("未找到验证码输入框");
}
} else {
console.error("验证码解析失败:", data.error || "未知错误");
}
},
onerror: function (error) {
console.error("请求后端失败:", error);
}
});
}
/**
* 根据XPath获取异步加载的DOM元素
* @param {string} xpath - XPath表达式
* @param {number} timeout - 超时时间(毫秒),默认5000ms
* @returns {Promise<HTMLElement|null>} - 匹配到的元素或null
*/
function waitForElementByXpath(xpath, timeout = 5000) {
return new Promise((resolve, reject) => {
const startTime = Date.now();
// 使用 MutationObserver 监听 DOM 变化
const observer = new MutationObserver(() => {
const element = getElementByXpath(xpath);
if (element) {
observer.disconnect(); // 停止观察
resolve(element);
} else if (Date.now() - startTime > timeout) {
observer.disconnect(); // 超时后停止观察
reject(new Error("超时未找到元素"));
}
});
// 开始观察整个文档的变化
observer.observe(document.body, {childList: true, subtree: true});
// 如果超时仍未找到元素,拒绝 Promise
setTimeout(() => {
observer.disconnect();
reject(new Error("超时未找到元素"));
}, timeout);
});
}
(function () {
'use strict';
// 检查当前网站是否在列表中
const currentUrl = window.location.href;
const siteConfig = siteList.find(site => currentUrl.includes(site.url));
if (!siteConfig) {
console.log("当前网站不在目标列表中");
return;
}
console.log("匹配到目标网站:", siteConfig.url);
// 获取验证码图片元素
waitForElementByXpath(siteConfig.imageXpath)
.then((element) => {
// console.log("找到元素:", element);
if (!element) {
console.error("未找到验证码图片元素");
return;
}
// 获取图片的二进制数据(Base64编码)
getCaptchaImageAsBase64(element, (base64Image) => {
if (base64Image) {
// console.log("成功获取验证码图片的Base64编码");
// 发送验证码图片到后端接口进行解析
sendCaptchaToBackend(base64Image, siteConfig.valueXpath);
} else {
console.error("无法获取验证码图片的Base64编码");
}
});
}).catch((error) => {
console.error(error.message);
});
})();