您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
根据输入的XPath定位元素进行循环点击,可控制开始和停止,搜索不到元素时提示并停止,增加关闭按钮及可设置延时功能,优化XPath查找逻辑,添加界面可拖动伸缩、缩小功能及按指定文本查找点击元素功能,并美化界面布局
当前为
// ==UserScript== // @name 网页基于xpath|文本的自动点击(持续更新) // @namespace https://game.lpengine.cn/* // @version 1.0 // @description 根据输入的XPath定位元素进行循环点击,可控制开始和停止,搜索不到元素时提示并停止,增加关闭按钮及可设置延时功能,优化XPath查找逻辑,添加界面可拖动伸缩、缩小功能及按指定文本查找点击元素功能,并美化界面布局 // @author Your Name // @match https://fz.lpengine.cn/* // @match https://game.lpengine.cn/* // @grant GM_setValue // @grant GM.getValue // @grant GM_addStyle // ==/UserScript== (function () { 'use strict'; // 创建用于输入XPath、延时、指定文本以及显示状态的HTML元素,并设置样式使其在最上方显示,同时设置初始为可拖动状态 const inputDiv = document.createElement('div'); inputDiv.style.position = 'fixed'; inputDiv.style.top = '10px'; inputDiv.style.left = '10px'; inputDiv.style.zIndex = '9999'; inputDiv.style.backgroundColor = '#f8f9fa'; inputDiv.style.padding = '10px'; inputDiv.style.borderRadius = '5px'; inputDiv.style.boxShadow = '0 0 5px rgba(0, 0, 0, 0.2)'; inputDiv.style.userSelect = 'none'; // 防止文本被误选 inputDiv.draggable = true; // 设置可拖动 inputDiv.innerHTML = ` <div style="display: flex; flex-direction: column;"> <!-- XPath 相关 --> <div style="display: flex; align-items: center; margin-bottom: 10px;"> <label for="xpathInput" style="margin-right: 10px;">XPath表达式:</label> <input type="text" id="xpathInput" style="padding: 5px; border: 1px solid #ced4da; border-radius: 3px; width: 300px;" /> </div> <div style="display: flex; align-items: center; margin-bottom: 10px;"> <label for="xpathDelayInput" style="margin-right: 10px;">XPath延时(毫秒):</label> <input type="number" id="xpathDelayInput" style="padding: 5px; border: 1px solid #ced4da; border-radius: 3px; width: 100px;" value="300" /> </div> <div style="display: flex; align-items: center;"> <button id="startXPathButton" style="padding: 5px 10px; border: none; border-radius: 3px; background-color: #007bff; color: white; cursor: pointer;">开始点击(XPath)</button> <button id="stopXPathButton" style="padding: 5px 10px; border: none; border-radius: 3px; background-color: #dc3545; color: white; cursor: pointer;">停止点击(XPath)</button> </div> <!-- 文本相关 --> <div style="display: flex; align-items: center; margin-top: 15px; margin-bottom: 10px;"> <label for="textInput" style="margin-right: 10px;">指定文本:</label> <input type="text" id="textInput" style="padding: 5px; border: 1px solid #ced4da; border-radius: 3px; width: 200px;" /> </div> <div style="display: flex; align-items: center; margin-bottom: 10px;"> <label for="textDelayInput" style="margin-right: 10px;">文本延时(毫秒):</label> <input type="number" id="textDelayInput" style="padding: 5px; border: 1px solid #ced4da; border-radius: 3px; width: 100px;" value="300" /> </div> <div style="display: flex; align-items: center;"> <button id="startTextButton" style="padding: 5px 10px; border: none; border-radius: 3px; background-color: #28a745; color: white; cursor: pointer;">开始点击(文本)</button> <button id="stopTextButton" style="padding: 5px 10px; border: none; border-radius: 3px; background-color: #6c757d; color: white; cursor: pointer;">停止点击(文本)</button> </div> <button id="closeButton" style="padding: 5px 10px; border: none; border-radius: 3px; background-color: #6c757d; color: white; cursor: pointer; margin-top: 15px;">关闭</button> <button id="minimizeButton" style="padding: 5px 10px; border: none; border-radius: 3px; background-color: #6c757d; color: white; cursor: pointer; margin-top: 5px;">缩小</button> <span id="status" style="margin-left: 10px; color: #6c757d; margin-top: 10px;">状态: 未开始</span> </div> `; document.body.appendChild(inputDiv); // 用于记录鼠标按下时的坐标,实现拖动功能 let startX, startY; // 为可拖动元素添加鼠标按下、移动和抬起事件监听器,正确实现拖动功能 inputDiv.addEventListener('mousedown', function (e) { startX = e.clientX; startY = e.clientY; document.addEventListener('mousemove', drag); document.addEventListener('mouseup', stopDrag); }); function drag(e) { const dx = e.clientX - startX; const dy = e.clientY - startY; inputDiv.style.left = (parseInt(inputDiv.style.left) || 0) + dx + 'px'; inputDiv.style.top = (parseInt(inputDiv.style.top) || 0) + dy + 'px'; startX = e.clientX; startY = e.clientY; } function stopDrag() { document.removeEventListener('mousemove', drag); document.removeEventListener('mouseup', stopDrag); } // 记录界面是否最小化 let isMinimized = false; // 缩小按钮点击事件处理函数 function minimize() { if (isMinimized) { // 如果已最小化,恢复原始大小 inputDiv.style.width = 'auto'; inputDiv.style.height = 'auto'; isMinimized = false; } else { // 如果未最小化,缩小界面 inputDiv.style.width = '30px'; inputDiv.style.height = '30px'; isMinimized = true; } } // 获取相关DOM元素 const xpathInput = document.getElementById('xpathInput'); const xpathDelayInput = document.getElementById('xpathDelayInput'); const startXPathButton = document.getElementById('startXPathButton'); const stopXPathButton = document.getElementById('stopXPathButton'); const textInput = document.getElementById('textInput'); const textDelayInput = document.getElementById('textDelayInput'); const startTextButton = document.getElementById('startTextButton'); const stopTextButton = document.getElementById('stopTextButton'); const closeButton = document.getElementById('closeButton'); const minimizeButton = document.getElementById('minimizeButton'); const statusSpan = document.getElementById('status'); // 初始化保存的XPath值、延时值和指定文本值(如果存在) (async () => { const savedXPath = await GM.getValue('savedXPath', ''); const savedXPathDelay = await GM.getValue('savedXPathDelay', 300); const savedText = await GM.getValue('savedText', ''); const savedTextDelay = await GM.getValue('savedTextDelay', 300); xpathInput.value = savedXPath; xpathDelayInput.value = savedXPathDelay; textInput.value = savedText; textDelayInput.value = savedTextDelay; })(); // 递归遍历所有节点(包括跨iframe、处理Shadow DOM等)查找元素的函数(XPath方式) function findElementsByXPathInAllContexts(xpath, context = document) { const results = []; const iterate = (node) => { const elements = document.evaluate(xpath, node, null, XPathResult.ANY_TYPE, null).iterateNext(); while (elements) { results.push(elements); elements = document.evaluate(xpath, node, null, XPathResult.ANY_TYPE, null).iterateNext(); } const shadowRoots = node.querySelectorAll('*'); shadowRoots.forEach((element) => { if (element.shadowRoot) { iterate(element.shadowRoot); } }); const iframes = node.querySelectorAll('iframe'); for (const iframe of iframes) { try { const iframeDoc = iframe.contentDocument || iframe.contentWindow.document; iterate(iframeDoc); } catch (error) { continue; } } }; iterate(context); return results; } // 递归遍历所有节点(包括跨iframe、处理Shadow DOM等)查找包含指定文本元素的函数 function findElementsByTextInAllContexts(text, context = document) { const results = []; const iterate = (node) => { const elements = node.querySelectorAll('*'); elements.forEach((element) => { if (element.textContent.includes(text)) { results.push(element); } }); const shadowRoots = node.querySelectorAll('*'); shadowRoots.forEach((element) => { if (element.shadowRoot) { iterate(element.shadowRoot); } }); const iframes = node.querySelectorAll('iframe'); for (const iframe of iframes) { try { const iframeDoc = iframe.contentDocument || iframe.contentWindow.document; iterate(iframeDoc); } catch (error) { continue; } } }; iterate(context); return results; } // 等待页面加载完成(包括所有资源、iframe等加载完毕)后再执行查找等操作的函数 function waitForPageLoad(callback) { if (document.readyState === 'complete') { callback(); } else { window.addEventListener('load', callback); } } // 开始点击的函数(基于XPath) async function startClickingByXPath() { const xpath = xpathInput.value; const delay = parseInt(xpathDelayInput.value, 10); GM_setValue('savedXPath', xpath); GM_setValue('savedXPathDelay', delay); let intervalId; try { waitForPageLoad(() => { intervalId = setInterval(async () => { const elements = findElementsByXPathInAllContexts(xpath); if (elements.length > 0) { for (const element of elements) { element.click(); } } else { clearInterval(intervalId); alert('未找到匹配XPath的元素,已停止点击。'); statusSpan.textContent = '状态: 已停止(未找到元素)'; } }, delay); statusSpan.textContent = '状态: 正在点击(XPath)'; }); } catch (error) { clearInterval(intervalId); alert('执行过程出现错误,请检查XPath表达式是否正确。'); statusSpan.textContent = '状态: 已停止(出错)'; } } // 开始点击的函数(基于指定文本) async function startClickingByText() { const text = textInput.value; const delay = parseInt(textDelayInput.value, 10); GM_setValue('savedText', text); GM_setValue('savedTextDelay', delay); let intervalId; try { waitForPageLoad(() => { intervalId = setInterval(async () => { const elements = findElementsByTextInAllContexts(text); if (elements.length > 0) { for (const element of elements) { element.click(); } } else { clearInterval(intervalId); alert('未找到包含指定文本的元素,已停止点击。'); statusSpan.textContent = '状态: 已停止(未找到元素)'; } }, delay); statusSpan.textContent = '状态: 正在点击(文本)'; }); } catch (error) { clearInterval(intervalId); alert('执行过程出现错误,请检查输入的文本是否正确。'); statusSpan.textContent = '状态: 已停止(出错)'; } } // 为开始按钮(XPath方式)添加点击事件监听器 startXPathButton.addEventListener('click', startClickingByXPath); // 为停止按钮(XPath方式)添加点击事件监听器 stopXPathButton.addEventListener('click', () => { if (window.xPathIntervalId) { clearInterval(window.xPathIntervalId); statusSpan.textContent = '状态: 已停止'; } }); // 为开始按钮(文本方式)添加点击事件监听器 startTextButton.addEventListener('click', startClickingByText); // 为停止按钮(文本方式)添加点击事件监听器 stopTextButton.addEventListener('click', () => { if (window.textIntervalId) { clearInterval(window.textIntervalId); statusSpan.textContent = '状态: 已停止'; } }); // 为关闭按钮添加点击事件监听器,点击后移除整个输入框区域 closeButton.addEventListener('click', () => { inputDiv.remove(); }); // 为缩小按钮添加点击事件监听器 minimizeButton.addEventListener('click', minimize); })();