当前位置: 首页 > news >正文

可以自动点击网页按钮的 Chrome 插件(manifest_v3 20241008)

这是我针对一个 vue 单页应用做的自动点击插件。他可以在这个 vue 单页应用的某一个子页面加载时,自动点击页面上的按钮。

分享那个这个案例的意义在于,vue 单页应用不同于一般的网页,他有很多事件是不触发的,需要自己想办法处理。在这里要感谢“智谱清言”,只要问题问的够明确,他就可以帮助写出代码。

本项目包含如下几个文件:

background.js 代码如下:


chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {if (changeInfo.status === 'complete') {console.log(`插件:Tab ${tab.url} has completed loading.`);    // 发送消息给对应的tab的contentscriptchrome.tabs.sendMessage(tabId, "插件:background消息", function(response) {// 处理来自contentscript的响应(如果需要)console.log('插件:Response from contentscript:', response);});   }});

content-script1.js 代码如下:

// 这个函数的运行过程要去网页端 console 去看
// 获取当前时间
var currentTime = new Date();
var currentHour = currentTime.getHours();
var currentMinute = currentTime.getMinutes();
var currentSecond = currentTime.getSeconds();
console.log('插件------------------');
console.log('插件开始执行。当前时间:' + currentHour + ':' + currentMinute + ':' + currentSecond);function checkURL(url){// console.log('插件:checkURL:'+url);var flag = false;if(typeof url == "undefined" || null == url)url = window.location.href; // var regex = /.*\:\/\/.*\/form.php/;// var regex = /https\:\/\/.*pretreatment.*/;var regex = /http\:\/\/.*\/#\/basic\/list\?type=1/;var match = url.match(regex);if(typeof match != "undefined" && null != match) {console.log('插件:匹配到待签收页面。');flag = true;}return flag;
}function getCurrentTab(){return window.location.href;
}function sleep(ms) {return new Promise(resolve => setTimeout(resolve, ms));
}class XFXS_filter{constructor() {}find_inputButton(){        this.XFXS_input = document.evaluate('//label[contains(text(),"形")]/following-sibling::div/div/div/input', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;if (this.XFXS_input == null){// console.log('插件:XFXS_input为空。');return null;} else {// console.log('插件:XFXS_input不为空。');// console.log(this.XFXS_input);return this.XFXS_input;}}changeColor_XFXS() {// 修改背景色// 查找所有具有指定类名的divvar divs = document.querySelectorAll('div.el-form-item.el-form-item--mini');// 过滤出包含innerText为"事项"的label的divvar targetDiv = Array.from(divs).find(function(div) {return Array.from(div.querySelectorAll('label')).some(function(label) {return label.innerText.includes("xing");});});// console.log('插件:targetDiv:');// console.log(targetDiv); // 输出找到的div元素,如果没有找到则为undefinedtargetDiv.style.backgroundColor = "red";var labels = document.querySelectorAll('label.el-form-item__label');for (var i = 0; i < labels.length; i++) {// 检查 innerText 是否为“形”if (labels[i].innerText === '形') {// 如果是,则执行相应操作,例如打印出来或者修改样式// console.log('插件:targetlabel:');// console.log(labels[i]);// 例如,将找到的 label 文本颜色设置为蓝色labels[i].style.color = 'yellow';}}}async click_to_find_listnode(){this.XFXS_input.click();let sleep_gap = 150;await sleep(sleep_gap);this.XFXS_dropdown_w = document.evaluate('//div[contains(@style, "position: absolute")]/div[@class="el-scrollbar"]/div/ul/li/span[text()="网"]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;this.ChaXun = document.evaluate('//span[@class="btn matters" and text()="询"]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;this.XFXS_dropdown_w.click();await sleep(sleep_gap);console.log('插件:已点击。');this.ChaXun.click();await sleep(sleep_gap);console.log('插件:点选按钮结束。');}
}function inputValue(dom, st) { var evt = new InputEvent('input', { inputType: 'insertText', data: st, dataTransfer: null, isComposing: false }); dom.value = st; dom.dispatchEvent(evt); 
} chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {console.log('插件:Received details:'+message);sendResponse({msg: "插件:content_script_response"});   console.log('插件:check_action 开始。');if (checkURL(getCurrentTab())) {var XFXS_filter_instance = new XFXS_filter();XFXS_filter_instance.find_inputButton();if ( null != XFXS_filter_instance.XFXS_input && XFXS_filter_instance.XFXS_input.value == '' ){console.log('插件:XFXS_filter_instance.XFXS_input 找到了且值为空。');// console.log(XFXS_filter_instance.XFXS_input);XFXS_filter_instance.changeColor_XFXS();XFXS_filter_instance.click_to_find_listnode();} else {console.log('插件:XFXS_filter_instance.XFXS_input 没找到或有值。');}}});document.addEventListener("DOMContentLoaded", function() {var xpathExpression = "//*[contains(@style, 'position: absolute')]";var result = document.evaluate(xpathExpression, document, null, XPathResult.ANY_TYPE, null);var node;while (node = result.iterateNext()) {// 这里可以对找到的每个节点进行处理console.log("插件:发现一个可见节点。"); // 例如,打印节点}
});

manifest.json 的代码如下:


{"manifest_version": 3,"name": "助手","description": "辅助","version": "1.0","host_permissions": [ "http://11.11.11.11/" ],"permissions": ["tabs","activeTab","scripting","webRequest","webRequestBlocking"],"background": {"service_worker": "background.js"},"content_scripts": [{"matches": ["http://11.11.11.11/"],"js": ["content-scripts1.js"]}],"action": {"default_icon": "Bw.png","default_title": "辅助","default_popup":"usr_input.html"}  
}

写几点经验:

1、调试时 background.js 的 console.log 的输出可以在浏览器插件页面(如下图的按钮点进去)中看到。content-script1.js 的日志输出是在网页打开后,打开“开发者工具”的控制台,里面可以看到。因为content-script1.js 是注入到特定网页的。


2、本项目涉及到的这个 vue 单页应用的网址中是包含“#”号的。但是子网页变化时,它并不触发onoad、onhashchange 事件。所以这里使用了 onUpdated 事件。在 manifest.json 配置文件中,想在网址中填带“#”的网址也是没用的,插件不支持。所以就直接填“#”前面的网址了。

3、学习插件最快的方式还是看官方 文档 。先了解全貌,然后才能向 AI 问出有针对性的问题,AI 才能直接给出准确的代码。


http://www.mrgr.cn/news/45574.html

相关文章:

  • C语言复习题
  • 一分钟掌握 Java21 新特性
  • AOP(面向切面编程)
  • Java中的五种引用类型
  • [NewStar2024]
  • 在spring boot项目中使用Spring Security的BCryptPasswordEncoder类进行相同密码不同密文的加密和验证
  • tensorflow快速入门--如何定义张量、定义网络结构、超参数设置、模型训练???
  • 机器学习初步【1】
  • YOLO11改进|注意力机制篇|引入MSCA注意力机制
  • 在JavaScript中,改变this指向的call,apply,bind有什么区别,原理分别是什么?
  • df 的各种用法 以及与du 的区别
  • 【Python】文件及目录
  • JavaSE - 基础语法
  • QT入门介绍篇
  • 【stm32】寄存器(stm32技术手册下载链接)
  • 远程控制软件推荐:亲测好用!
  • torch和torchvision 版本对应
  • var let const 之间的区别
  • 26. 删除有序数组中的重复项
  • 五十、架构设计经验与技巧(架构设计基本原则)