Javascript 木偶演员在返回HTML之前未触发单击
My Node.js Puppeter脚本成功填写表单,但页面在返回修改后的页面内容之前的某段时间内只接受元素上的“单击”事件。以下是脚本:Javascript 木偶演员在返回HTML之前未触发单击,javascript,node.js,events,xmlhttprequest,puppeteer,Javascript,Node.js,Events,Xmlhttprequest,Puppeteer,My Node.js Puppeter脚本成功填写表单,但页面在返回修改后的页面内容之前的某段时间内只接受元素上的“单击”事件。以下是脚本: const fetchContracts = async (url) => { const browser = await pupeteer.launch({ headless: true, args: ['--no-sandbox', '--disable-setuid-sandbox']}); const page = await
const fetchContracts = async (url) => {
const browser = await pupeteer.launch({ headless: true, args: ['--no-sandbox', '--disable-setuid-sandbox']});
const page = await browser.newPage();
const pendingXHR = new PendingXHR(page);
await page.goto(url, { waitUntil: 'networkidle2' });
await Promise.all([
page.click("#agree_statement"),
page.waitForNavigation()
]);
await page.click(".form-check-input");
await Promise.all([
page.click(".btn-primary"),
page.waitForNavigation()
]);
/// MY PROBLEM OCCURS HERE
/// Sometimes these clicks do not register....
await page.click('#filedReports th:nth-child(5)')
await pendingXHR.waitForAllXhrFinished();
await page.click('#filedReports th:nth-child(5)');
await pendingXHR.waitForAllXhrFinished();
/// And my bot skips directly here....
let html = await page.content();
await page.close();
await browser.close();
return html;
}
“pendingXHR”模块是一个导入,我将其从库中的代码顶部拉入:
该脚本在我的本地计算机上运行,并且在我将脚本上传到Digital Ocean的某些时候也能运行。根据我正在爬行的页面,这些单击会启动XHR请求,我正在尝试等待。以下是证据:
所以我的问题是:
为什么这些点击不会注册,即使我正在等待它们并等待XHR请求,在html从页面中提取并返回之前?为什么与此不一致,有时点击被注册,有时不被注册
感谢您的帮助。您是否尝试过以下解决方法:
await page.waitfor(1000);// this line will wait for 1 Sec
这样,您可以确保它已加载
更好的方法是放置页面。单击承诺。所有内容如下:
await Promise.all([
await page.click('#filedReports th:nth-child(5)'),
await pendingXHR.waitForAllXhrFinished()
]);
附言:你的分号丢失了
/// MY PROBLEM OCCURS HERE
/// Sometimes these clicks do not register....
\/
await page.click('#filedReports th:nth-child(5)')
await pendingXHR.waitForAllXhrFinished(); /\
await page.click('#filedReports th:nth-child(5)');
await pendingXHR.waitForAllXhrFinished();
简短回答:单击将导致延迟的AJAX请求,因此
pendingXHR.waitForAllXhrFinished()
将立即解决,因为在执行函数时没有发生任何请求。改用page.waitForResponse('../data/')
问题
您预计将发生以下事件过程:
pendingXHR.waitForAllXhrFinished()
已执行pendingXHR.waitForAllXhrFinished()
解析page.content()
已执行pendingXHR.waitForAllXhrFinished()
已执行pendingXHR.waitForAllXhrFinished()
立即解析(因为没有请求)page.content()
执行(太早了!)pendingXHR.waitForAllXhrFinished()
已执行pendingXHR.waitForAllXhrFinished()
解析page.content()
(太早了!)pendingXHR.waitForAllXhrFinished
来解决,因为这样可以确保对data/
的请求实际发生
修复第二种情况(如果需要)并不是那么简单,但是可以通过使用引入固定的等待时间来完成
通过修复这两种情况,新代码如下所示:
wait Promise.all([//等待响应发生并单击
page.waitForResponse(“…/data/”),//在此处使用实际URL
第页。单击(“…”),
]);
等待页面。等待(10);//等待可能发生的任何异步重新加载
让html=等待page.content();
谢谢。这是非常好的解释,我将不再依赖于第三方库,现在我知道这个page.waitForResponse存在,我可以使用它来等待特定的资源。
/// MY PROBLEM OCCURS HERE
/// Sometimes these clicks do not register....
\/
await page.click('#filedReports th:nth-child(5)')
await pendingXHR.waitForAllXhrFinished(); /\
await page.click('#filedReports th:nth-child(5)');
await pendingXHR.waitForAllXhrFinished();