我是 puppeteer 的新手,试图通过编写一个简单的抓取作业来了解它的工作原理。
我打算做什么
计划很简单:
- 转到一个页面,
- 然后提取所有
<li>
<ul>
下的链接标签 - 单击每个
<li>
链接并截取目标页面的屏幕截图。
我是如何实现的
代码如下,
await page.goto('http://some.url.com'); // step-1
const a_elems = await page.$$('li.some_css_class a'); // step-2
for (var i=0; i<a_elems.length; i++) { // step-3
const elem = a_elems[i];
await Promise.all([
elem.click(),
page.waitForNavigation({waitUntil: 'networkidle0'}) // click each link and wait page loading
]);
await page.screenshot({path: `${IMG_FOLDER}/${txt}.png`});
await page.goBack({waitUntil: 'networkidle0'}); // go back to previous page so that we could click next link
console.log(`clicked link = ${txt}`);
}
出了什么问题,需要帮助
然而,上面的代码只能处理a_elems
中的第一个链接。 ,当 for-loop
来到第二个链接,代码中断并显示错误
(node:40606) UnhandledPromiseRejectionWarning: Error: Node is detached from document
at ElementHandle._scrollIntoViewIfNeeded (.../.npm-packages/lib/node_modules/puppeteer/lib/JSHandle.js:203:13)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async ElementHandle.click (.../.npm-packages/lib/node_modules/puppeteer/lib/JSHandle.js:282:5)
at async Promise.all (index 0)
at async main (.../test.js:34:5)
-- ASYNC --
at ElementHandle.<anonymous> (.../.npm-packages/lib/node_modules/puppeteer/lib/helper.js:111:15)
at main (.../test.js:35:12)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
我怀疑 page
的执行上下文单击第一个链接后已经更改,即使我调用了 page.goBack
到上一页,但它没有给我以前的执行上下文。
不确定我的猜测是否正确,也没有找到类似的问题,希望能得到一些帮助,谢谢!
如果有更好的实现方式来实现我的计划,请告诉我。
最佳答案
当您 goBack
时,您认为元素会丢失其上下文是正确的。那是行不通的。
但是,正如您评论的那样,您可以从元素中获取 href
并从那里开始:
for (var i=0; i<a_elems.length; i++) { // step-3
const elem = a_elems[i];
const href = await page.evaluate(e => e.href, elem); //Chrome will return the absolute URL
const newPage = await browser.newPage();
await newPage.goto(href);
await newPage.screenshot({path: `${IMG_FOLDER}/${txt}.png`});
await newPage.close();
console.log(`clicked link = ${txt}`);
}
您甚至可以并行执行此操作,尽管有一个用于屏幕截图的内部队列。
关于javascript - 如何单击 puppeteer 中的一系列链接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58905844/