如何用JavaScript编写表单自动填写脚本及修复Puppeteer循环不执行问题
问题排查与修复方案
原生浏览器端JS脚本失效原因
你最初写的浏览器端脚本无法实现需求,核心原因如下:
- 执行
window.location.href跳转页面后,当前页面的全部JS运行上下文会被直接销毁,后续的fillForm、submitForm函数根本没有执行机会 - 所有逻辑是同步执行的,不会等待页面跳转加载完成就调用表单操作函数,自然找不到目标页面的DOM元素
- 代码中
setTimeout(timeout, 3000)的timeout函数未定义,也无法实现等待页面加载完成的效果
这类跨页面重复自动化操作本身就不适合用前端浏览器脚本实现,切换到Puppeteer是正确的技术选型。
Puppeteer脚本仅执行一次循环的原因
问题出在代码的时序和资源释放逻辑上:
- 你将
await browser.close()写在了循环体内部,第一次循环执行完成就直接关闭了整个浏览器实例,后续循环无法新建页面执行任务 - 按钮点击操作没有加
await,部分场景下点击动作还没触发就执行了后续逻辑,可能导致提交失效 - 点击提交按钮后没有配置等待页面跳转的逻辑,部分表单提交后刷新的场景下可能出现时序异常
修复后可正常循环的代码
const puppeteer = require('puppeteer'); async function main(){ const browser = await puppeteer.launch({ headless: false }); for (let i=0; i<3; i++){ const page = await browser.newPage(); await page.goto('https://beispiel.de/'); await page.type('#gender', 'Herr'); await page.type('#lastname', 'Beispiel'); await page.type('#firstname', 'Beispiel'); await page.type('#address', 'Beispiel 29'); await page.type('#postcode', 'Beispiel'); await page.type('#city', 'Beispiel'); await page.type('#mobile', '0041797766666'); await page.type('#email', 'Beispiel@outlook.com'); await page.type('#country_code', 'Deutschland'); await page.type('#birthday', '28.07.1995'); await page.type('#profession', 'Beispiel'); await page.type('#hobbies', 'Beispiel'); await page.type('#skills', 'Beispiel'); await page.type('#wish', 'Beispiel'); await (await page.waitForSelector('#agb-checkbox')).click(); const searchBtn = await page.$x("//button[@class='form-btn']"); // 点击操作添加await保证触发成功 await searchBtn[0].click(); // 若提交后页面跳转可打开下方注释,等待跳转完成 // await page.waitForNavigation({ waitUntil: 'networkidle2' }); await page.waitForTimeout(5000); // 关闭当前页面释放内存,不影响浏览器实例 await page.close(); } // 所有循环执行完成后再关闭浏览器 await browser.close(); } main();
内容的提问来源于stack exchange,提问作者Fifa Kingz
相关产品推荐
相关产品推荐

