使用浏览器控制台js定时点击网页按钮

为了这个简单的功能折腾了半天,我可以搞定的。
本来想弄Selenium 、Power Automate,但是都因为中间环节出问题,疯了,还是搞JavaScript吧,但是我前端又不熟悉啊,后悔没好好学习前端了,想着学习C++更高大上,关键你做的工作也没发挥C++的潜力,你应该找浏览器这种C++工作。
不管了,你还是用JavaScript吧。
https://openi.pcl.ac.cn/eatcosmos/init-openi/debugjob?debugListType=all

chatgpt

浏览器控制台 JavaScript 实现如下功能
//循环开始
//等待"再次调试"按钮class不为"disable"
//选择点击"再次调试"按钮,xpath是 /html/body/div[2]/div[3]/div[2]/div[1]/div[2]/div[1]/div/div[3]/table/tbody/tr[1]/td[6]/div/div/a[1]

//等待2分钟

//选择点击"停止"按钮,xpath是/html/body/div[2]/div[3]/div[2]/div[1]/div[2]/div[1]/div/div[3]/table/tbody/tr[1]/td[6]/div/div/a[2]
//循环结束

Person:

  • 浏览器控制台 JavaScript 实现如下功能
    //循环开始
    //等待"再次调试"按钮class不为"disable"
    //选择点击"再次调试"按钮,xpath是 /html/body/div[2]/div[3]/div[2]/div[1]/div[2]/div[1]/div/div[3]/table/tbody/tr[1]/td[6]/div/div/a[1]

//等待2分钟

//选择点击"停止"按钮,xpath是/html/body/div[2]/div[3]/div[2]/div[1]/div[2]/div[1]/div/div[3]/table/tbody/tr[1]/td[6]/div/div/a[2]
//循环结束

ChatGPT:

  • 你可以使用以下 JavaScript 代码实现你描述的功能:
async function waitForElement(selector) {
    while (document.querySelector(selector).classList.contains("disable")) {
        await new Promise(resolve => setTimeout(resolve, 1000));
    }
}

async function clickElementByXPath(xpath) {
    const element = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
    element.click();
}

async function main() {
    // 循环开始
    while (true) {
        // 等待"再次调试"按钮class不为"disable"
        await waitForElement(".your-button-class"); // 替换为实际的按钮类名

        // 选择点击"再次调试"按钮
        const againDebugXPath = "/html/body/div[2]/div[3]/div[2]/div[1]/div[2]/div[1]/div/div[3]/table/tbody/tr[1]/td[6]/div/div/a[1]";
        await clickElementByXPath(againDebugXPath);

        // 等待2分钟
        await new Promise(resolve => setTimeout(resolve, 2 * 60 * 1000));

        // 选择点击"停止"按钮
        const stopXPath = "/html/body/div[2]/div[3]/div[2]/div[1]/div[2]/div[1]/div/div[3]/table/tbody/tr[1]/td[6]/div/div/a[2]";
        await clickElementByXPath(stopXPath);
    }
}

main();

请注意,这只是一个基本的示例,你需要替换实际的按钮类名和XPath。XPath 通常比较脆弱,可能会受到页面结构变化的影响。最好使用更稳定的选择器,如类名、ID 或其他属性。确保你的网页结构稳定,以便脚本正常运行。

Person:

  • VM6778:2 Uncaught (in promise) DOMException: Failed to execute ‘querySelector’ on ‘Document’: The provided selector is empty.

ChatGPT:

  • 这个错误表明在调用 document.querySelector(selector) 时提供的选择器为空。这可能是由于你传递给 waitForElement 函数的选择器没有匹配到任何元素导致的。

确保你传递给 waitForElement 函数的选择器是正确的,并且它能够匹配到页面上的元素。你可以在浏览器的控制台手动运行这些函数并检查选择器是否有效。如果选择器有效,但页面结构可能在运行脚本期间发生变化,你可能需要调整选择器或在选择器之前加入适当的等待。

如果问题仍然存在,请提供你的完整 JavaScript 代码和页面结构,以便更详细地检查并提供帮助。

Person:

  • async function waitForElement(selector) {
    while (document.querySelector(selector).classList.contains(“disable”)) {
    await new Promise(resolve => setTimeout(resolve, 1000));
    }
    }
    selector 参数可以传递xpath吗,希望传递一个 再次调试 的xpath变量进去

ChatGPT:

  • document.querySelector 函数通常用于 CSS 选择器,而不是 XPath。如果你想使用 XPath,你可以使用 document.evaluate 方法,但是它返回的是一个 XPathResult 对象而不是直接的元素。因此,你需要调整你的 waitForElement 函数来处理 XPath。

下面是一个修改后的代码片段:

async function waitForElement(xpath) {
    const getElement = () => document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;

    while (getElement() && getElement().classList.contains("disable")) {
        await new Promise(resolve => setTimeout(resolve, 1000));
    }
}

// 使用示例
const xpath = "/html/body/div[2]/div[3]/div[2]/div[1]/div[2]/div[1]/div/div[3]/table/tbody/tr[1]/td[6]/div/div/a[1]";
await waitForElement(xpath);

在这里,waitForElement 函数接受一个 XPath,使用 document.evaluate 获取相应的元素,然后检查该元素的类名是否包含 “disable”。这样,你可以传递 XPath 作为参数,并等待相应的元素状态。

Person:

  • await clickElementByXPath(againDebugXPath);
    await什么作用?直观显示

ChatGPT:

  • await 是用于异步 JavaScript 中的关键字,它通常与 async 函数一起使用。await 用于等待一个 Promise 对象的解决(fulfillment)或拒绝(rejection)。在这个上下文中,await 用于等待 clickElementByXPath(againDebugXPath) 这个异步函数执行完毕。

在你的代码中,clickElementByXPath 函数可能包含一些异步的操作,比如 DOM 元素的点击,可能需要一些时间才能完成。使用 await 关键字,它会让 JavaScript 运行时等待这个异步操作完成,然后再继续执行下一个语句。

在这里,await clickElementByXPath(againDebugXPath); 的作用是等待点击元素的操作完成,确保在执行下一步之前,必须等到点击操作执行完成。如果没有 await,代码将不会等待异步操作完成,可能会导致后续的代码在异步操作执行之前就执行了。

Person:

  • async function waitForElement(xpath) {
    const getElement = () => document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;

    while (getElement() && getElement().classList.contains(“disable”)) {
    await new Promise(resolve => setTimeout(resolve, 1000));
    }
    }

// 使用示例
const againDebugXPath = “/html/body/div[2]/div[3]/div[2]/div[1]/div[2]/div[1]/div/div[3]/table/tbody/tr[1]/td[6]/div/div/a[1]”;
const stopXPath = “/html/body/div[2]/div[3]/div[2]/div[1]/div[2]/div[1]/div/div[3]/table/tbody/tr[1]/td[6]/div/div/a[2]”;

async function clickElementByXPath(xpath) {
const element = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
element.click();
}

async function main() {
// 循环开始
while (true) {
// 等待"再次调试"按钮class不为"disable"
await waitForElement(againDebugXPath);
// 选择点击"再次调试"按钮
await clickElementByXPath(againDebugXPath);

  // 等待2分钟
  await new Promise(resolve => setTimeout(resolve, 1 * 60 * 1000));

  // 等待"停止"按钮class不为"disable"

  // 选择点击"停止"按钮
  await clickElementByXPath(stopXPath);

}
}

main();

Promise {}[[Prototype]]: Promise[[PromiseState]]: “pending”[[PromiseResult]]: undefined 打印这些什么意思?

为什么停止了?应该循环的啊,点击停止后似乎推出循环了?

ChatGPT:

  • 你的代码在执行时会进入一个无限循环,并且在点击"停止"按钮后似乎陷入了问题。原因可能是点击"停止"按钮后,可能导致页面的重新加载或发生了一些其他影响循环的事件。此外,在你的代码中没有包含等待"停止"按钮状态不为"disable"的逻辑,这也可能导致问题。

为了更好地调试和了解发生了什么,你可以在循环中加入一些日志输出,以便在控制台中查看程序执行的过程。例如:

async function main() {
  // 循环开始
  while (true) {
      console.log("Waiting for '再次调试' button...");
      // 等待"再次调试"按钮class不为"disable"
      await waitForElement(againDebugXPath);
      console.log("Clicking '再次调试' button...");
      // 选择点击"再次调试"按钮
      await clickElementByXPath(againDebugXPath);

      console.log("Waiting for 2 minutes...");
      // 等待2分钟
      await new Promise(resolve => setTimeout(resolve, 2 * 60 * 1000));

      console.log("Waiting for '停止' button...");
      // 等待"停止"按钮class不为"disable"
      await waitForElement(stopXPath);
      
      console.log("Clicking '停止' button...");
      // 选择点击"停止"按钮
      await clickElementByXPath(stopXPath);
  }
}

这样可以帮助你更清晰地看到程序执行的步骤,以便定位问题。

此外,你还可以考虑加入一些额外的安全机制,例如设置一个计数器,限制循环次数,以防止陷入无限循环。

Person:

  • await waitForElement(stopXPath);
    console.log(“Clicking ‘停止’ button…”); 能不能改成阻塞等待

ChatGPT:

  • 如果你想要等待waitForElement(stopXPath)完成后再执行后续的代码,可以将waitForElement 函数改为返回一个解决后的 Promise。在 waitForElement 函数的最后,当等待结束后,你可以使用 resolve 将 Promise 解决。

下面是修改的代码:

async function waitForElement(xpath) {
    return new Promise(resolve => {
        const checkElement = () => {
            const element = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
            if (element && !element.classList.contains("disable")) {
                resolve();
            } else {
                setTimeout(checkElement, 1000);
            }
        };

        checkElement();
    });
}

async function main() {
    // 循环开始
    while (true) {
        console.log("Waiting for '再次调试' button...");
        // 等待"再次调试"按钮class不为"disable"
        await waitForElement(againDebugXPath);
        console.log("Clicking '再次调试' button...");
        // 选择点击"再次调试"按钮
        await clickElementByXPath(againDebugXPath);

        console.log("Waiting for 2 minutes...");
        // 等待2分钟
        await new Promise(resolve => setTimeout(resolve, 2 * 60 * 1000));

        console.log("Waiting for '停止' button...");
        // 等待"停止"按钮class不为"disable"
        await waitForElement(stopXPath);

        console.log("Clicking '停止' button...");
        // 选择点击"停止"按钮
        await clickElementByXPath(stopXPath);
    }
}

这样,await waitForElement(stopXPath); 将等待 waitForElement 函数的解决,并在解决后执行后续的代码。

Person:

  • while (true) { 改为循环特定次数

ChatGPT:

  • 如果你想在循环特定的次数后结束,你可以使用一个计数器变量来追踪循环次数,并在达到特定次数时跳出循环。例如:
async function main() {
    const maxIterations = 10; // 设置循环的最大次数
    let iterationCount = 0;

    while (iterationCount < maxIterations) {
        console.log(`Iteration ${iterationCount + 1}`);

        console.log("Waiting for '再次调试' button...");
        // 等待"再次调试"按钮class不为"disable"
        await waitForElement(againDebugXPath);
        console.log("Clicking '再次调试' button...");
        // 选择点击"再次调试"按钮
        await clickElementByXPath(againDebugXPath);

        console.log("Waiting for 2 minutes...");
        // 等待2分钟
        await new Promise(resolve => setTimeout(resolve, 2 * 60 * 1000));

        console.log("Waiting for '停止' button...");
        // 等待"停止"按钮class不为"disable"
        await waitForElement(stopXPath);

        console.log("Clicking '停止' button...");
        // 选择点击"停止"按钮
        await clickElementByXPath(stopXPath);

        iterationCount++;
    }

    console.log(`Reached maximum iterations: ${maxIterations}`);
}

在这个例子中,maxIterations 是你想要执行的循环次数的上限。每次循环时,增加 iterationCount 的值,当 iterationCount 达到 maxIterations 时,循环就会结束。

Person:

  • 如何中断 控制台 死循环

ChatGPT:

  • 在控制台中执行的 JavaScript 代码如果陷入了死循环,可以通过以下几种方法中断:
  1. 手动停止脚本执行: 在浏览器的开发者工具中,你可以手动停止脚本的执行。通常,这可以通过点击开发者工具的“停止”按钮(一般是一个红色的方块)来实现。这会终止当前正在执行的脚本。
  2. 刷新页面: 刷新页面会导致当前的 JavaScript 执行中断,并重新加载页面。这可以通过浏览器刷新按钮或者使用快捷键(通常是 F5 或者 Ctrl+R)来完成。
  3. 关闭/重新打开开发者工具: 关闭开发者工具会中断当前的 JavaScript 执行。你可以通过关闭开发者工具,然后重新打开来中止脚本。
  4. ** 终止执行:** 在浏览器控制台中,你可以尝试使用 Ctrl+C 组合键来强制中断执行。在某些情况下,这可能会中断脚本。
  5. 清除控制台: 清除控制台的所有输出有时候也可以帮助中断执行。你可以通过执行 console.clear() 或者手动清除控制台来尝试。

请注意,这些方法的有效性可能取决于浏览器和具体的情况。在实际中,最好的做法是编写代码时注意避免死循环,或者在循环中添加一些条件来确保在合适的时候退出循环。

Person:

  • 完整代码
    async function waitForElement(xpath) {
    console.log(“async function waitForElement(xpath)…”);
    const getElement = () => document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;

    while (getElement() && getElement().classList.contains(“disabled”)) {
    console.log(“Waiting for element…”);
    await new Promise(resolve => setTimeout(resolve, 1000));
    }
    }

// 使用示例
const againDebugXPath = “/html/body/div[2]/div[3]/div[2]/div[1]/div[2]/div[1]/div/div[3]/table/tbody/tr[1]/td[6]/div/div/a[1]”;
const debugXPath = “/html/body/div[2]/div[3]/div[2]/div[1]/div[2]/div[1]/div/div[3]/table/tbody/tr[1]/td[6]/div/div/a[1]”;
const stopXPath = “/html/body/div[2]/div[3]/div[2]/div[1]/div[2]/div[1]/div/div[3]/table/tbody/tr[1]/td[6]/div/div/a[2]”;

async function clickElementByXPath(xpath) {
const element = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
element.click();
}

async function main() {
const maxIterations = 3; // 设置循环的最大次数
let iterationCount = 0;

while (iterationCount < maxIterations) {
console.log(“>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>”);
// 选择点击"再次调试"按钮
console.log(“Clicking ‘再次调试’ button…”);
await waitForElement(againDebugXPath); //等待disabled属性消失
await clickElementByXPath(againDebugXPath);
await waitForElement(debugXPath); //等待disabled属性消失

  //点击调试按钮
  //console.log("Clicking '调试' button...");
  //await clickElementByXPath(debugXPath);

  console.log("#######################################");
  console.log("Waiting for 28 minutes...");
  // 等待28分钟
  await new Promise(resolve => setTimeout(resolve, 28 * 60 * 1000));
  //await new Promise(resolve => setTimeout(resolve, 1 * 10 * 1000));
  
  // 选择点击"停止"按钮
  console.log("Clicking '停止' button...");
  //await waitForElement(stopXPath); //等待disabled属性消失
  await clickElementByXPath(stopXPath);

  iterationCount++;
  console.log("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");

}
}

main();

ChatGPT:

  • 看起来你的代码主要用于模拟在页面上进行一系列操作,并在每次迭代中等待一段时间。我留意到你在 waitForElement 函数中等待元素的类名不为 “disabled”,但在代码中你使用的是 “classList.contains(“disabled”)”。这可能会导致等待条件出现问题,因为你的代码中元素可能是 “classList.contains(“disable”)” 而不是 “classList.contains(“disabled”)”。

你可以调整 waitForElement 函数中的条件,确保与页面上元素的实际类名匹配。此外,你还可以加入一些错误处理机制,以便更好地了解在代码执行过程中是否出现了问题。下面是稍作修改的代码:

async function waitForElement(xpath, className) {
    console.log(`Waiting for element with XPath: ${xpath} and class: ${className}...`);
    
    const getElement = () => document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;

    while (getElement() && getElement().classList.contains(className)) {
        console.log("Element still has the expected class, waiting...");
        await new Promise(resolve => setTimeout(resolve, 1000));
    }
}

// 使用示例
const againDebugXPath = "/html/body/div[2]/div[3]/div[2]/div[1]/div[2]/div[1]/div/div[3]/table/tbody/tr[1]/td[6]/div/div/a[1]";
const debugXPath = "/html/body/div[2]/div[3]/div[2]/div[1]/div[2]/div[1]/div/div[3]/table/tbody/tr[1]/td[6]/div/div/a[1]";
const stopXPath = "/html/body/div[2]/div[3]/div[2]/div[1]/div[2]/div[1]/div/div[3]/table/tbody/tr[1]/td[6]/div/div/a[2]";

async function main() {
    const maxIterations = 3; // 设置循环的最大次数
    let iterationCount = 0;

    while (iterationCount < maxIterations) {
        console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        // 选择点击"再次调试"按钮
        console.log("Clicking '再次调试' button...");
        await waitForElement(againDebugXPath, "disable"); // 等待类名不为 "disable"
        await clickElementByXPath(againDebugXPath);
        await waitForElement(debugXPath, "disable"); // 等待类名不为 "disable"

        console.log("#######################################");
        console.log("Waiting for 28 minutes...");
        // 等待28分钟
        await new Promise(resolve => setTimeout(resolve, 28 * 60 * 1000));

        // 选择点击"停止"按钮
        console.log("Clicking '停止' button...");
        await clickElementByXPath(stopXPath);

        iterationCount++;
        console.log("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
    }
}

main();

请确保类名与页面上的实际类名匹配,并适时修改。如果你在执行中遇到问题,也可以检查浏览器控制台是否有错误消息,以帮助定位问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值