可以自动点击网页按钮的 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的contentscript
      chrome.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() {
        // 修改背景色
        // 查找所有具有指定类名的div
        var divs = document.querySelectorAll('div.el-form-item.el-form-item--mini');
        // 过滤出包含innerText为"事项"的label的div
        var 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元素,如果没有找到则为undefined
        targetDiv.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 才能直接给出准确的代码。

实现网页自动点击的工具软件,可同时监控点击页面内容变化并报警提示。适用于广告点击、提高网页点击率。支持链接点击、JS广告点击、IFRAM点击,支持同页面多点点击,多线程多网址多窗口点击。实现模拟鼠标单击、双击、右击功能。 1、支持单页面多目标点击、多页面多目标、框架页面点击、定时点击、多线程高速连续点击,自定义点击间隔时间。 2、程序后台点击或者前台显示点击效果,可完全隐藏运行。 3点击后续工作处理,屏蔽弹出窗口,强制关闭外部窗口。 4、可同时添加点击多个页面,支持导入网页所有链接,或指添加网址。 5、能自动点击一个页面的所有链接 6、点击时显示实时速度,自动统计点击效果与流量。 7、支持代理服务器,换IP点击。可导入大量免费代理服务器,可随机使用或环使用代理服务器,对代理服务器使用情况进行统计管理。 8、支持adsl自动重拔号换ip 9、支持浏览器伪装,操作系统伪装,来路伪装。 10、网页内容变化监控,包括网页脚本执行产生的变化。 11、网页内容关键字监控,同时监控多个关键字。 12、网页HTML元素级监控,支持网页区域监控,同时监控多个元素,进行数据比较。 13、网络故障监控,本地网络故障时报警。 14、点击失败监控,网站服务器出现问题,或网页打不开时报警。 15、监控报警处置方式:弹出提示对话框;声音提示;邮件提醒;任务中止;启动新任务;启动外部处置程序;保存当前页面;程序关闭;自动关机。 WINXP,WIN2003用户安装必须安装补丁Microsoft .NET Framework 2.0 Service Pack 2 注意是SP2补丁.
各位网友大家好,要运行此工具必需先设置好网页信息,点击菜单栏设置或用快捷键(Alt+E)进入到设置页面,设置页面其中包括三个Tab:基本配置、网页信息和数据库。基本配置:如果要运行页面点击自动刷新外网IP就要配置ADSL帐号,现在暂时只支持ADSL刷新外网IP。单独页面执行是已Html中div的id为标志,意思是循环只执行此选中项,默认是所有项目。IP数据表就是每执行一下点击网页都会记录下本次的IP,记录文件放在此工具的路径下的Data目录下的iptables.log文件,最小化启动程序就是启动此工具或最小化窗口后台托管运行,就像QQ一样挂着。循环重启软件运行此项是为了和刷新ADSL一起配合产生独立IP,因为每个浏览器都有Cookies,关闭浏览器就可以彻底清除Cookies产生独立访客(UV)了。如果同时选择了最小化启动程序可以用全局快捷键Ctrl+Alt+空格解除循环。网页信息:是一个表格可以进行添加、修改和删除。页面执行方式有两种:一是completed意思是等网页加载完毕后执行点击,二是thread多线程执行意思是加载页面3秒钟后再执行页面点击。各有各自的优点,如果发现其中一种执行方式实现不了可以用另外一种试一下。类型就是网页的链接返回类型,有两种一时纯url链接如:http://www.baidu.com,另一种是数据库SQL语句返回链接集。用数据库名加@加地址标志,在数据库Tab中配置。SQL语句一定要返回link结果集如:select concat(&#39;http://www.google.com/&#39;, url) link from table,在SQL语句中不要用双引号,要用单引号,否则会出错。现在支持MYSQL和MSSQL数据库。链接就是类型对应的文本。htmlID是html中div的id,这个是网站网页中要点击的定位点,是这个表的主键必须唯一。偏移坐标就是htmlID的相对偏移点,用英文逗号隔开如0,0。状态有两种Y和N,意思是是和否,默认是Y,就是如果您想停用此条记录不加入循环就改为N。独立IP,默认是N,就是在Data/iptables.log文件中没出现过的当为独立ip。双击单元格可以修改文本内容。点击最后的删除可以删除此行记录。修改或添加后可别忘记了按右下角的保存按钮哦。数据库tab表格简单明了就不多加说明了。如果有出现运行异常可以可以查看Data下的error.log错误日志文件。如果对此工具有何意见或建议可以点击意见反馈发送你的宝贵信息。此工具支持在线更新。如收到您的来信,我会尽快的修改更新。温馨提示:目标执行标签(htmlID)要保持在预览窗口显示,建议最大化窗口最小化后台托管运行。希望此工具可以帮得了大家。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值