[英]How to use a for loop with puppeteer
我正在从 Facebook Marketplace 抓取数据。 我想要做的是使用 puppeteer 来:1)创建一个包含我所有列表名称的节点列表 2)使用 for 循环单击列表名称以弹出更多信息 3)从弹出窗口中抓取数据并保存到数组 4) 关闭弹出窗口 5) 对每个列表重复该过程以返回数组数据
这是我目前无法使用的代码:
const postClick = async (page) => {
await page.evaluate(() => {
//Capture the nodelist of listing names
let buttons = document.querySelectorAll('#marketplace-modal-dialog-title');
//If the nodelist of listings exist
if(buttons.length) {
//Loop through all listing names
for(let i = 0; i < buttons.length; i++) {
let button = buttons[i];
//click the listing
button.click();
//wait for the X button to appear
async (page) => {
await page.waitForSelector("button._3-9a._50zy._50-1._50z_._5upp._42ft");
await page.waitFor(5000)
await page.evaluate(() =>{
//click the X button
document.querySelector('button._3-9a._50zy._50-1._50z_._5upp._42ft').click();
});
}
}
}
});
}
然后我在浏览器关闭之前调用它:
await postClick(page);
我没有收到错误,但代码没有运行。 一旦我取出 for 循环并让 button = buttons[0]; 该代码仅针对第一项运行。
#marketplace-modal-dialog-title
通过 id 捕获元素表明页面中只存在 1 个项目,因为 id 应该是唯一的......我不知道为什么脸书有多个具有相同 id 的元素,但也许 js 正在对此做出反应,仅捕获 1 个元素
尝试按类捕获按钮
let buttons = await page.$$('._50f4._50f7');
或任何document.querySelectorAll
等价物(您可以使用page.$$
多个元素捕获到数组中)
此外, buttons.length
通过if(buttons.length)
返回一个数字,您正在检查true
或false
而不是数字,所以它应该是if(buttons.length > 0)
虽然有些语言认为0
为 false 并且这有效但它不是总的来说是个好主意
我现在无法测试此代码,可能会有一些错误,但这就是我要做的
// capture all the items in the marketplacee
let elements = await page.$$('._7yc._4e36');
// loop trough items
for (let i = 0; i < elements.length; i++) {
// capturing button and its text
let button = await elements[i].$('._50f4._50f7');
let button_text = await page.evaluate(el => el.innerText, button);
console.log(button_text);
// click the button
await button.click();
// wait for the popup to show up
await page.waitForSelector('.uiLayer' , { visible: true , timeout: 0 });
//close the popup
await page.click('._3-9a._50zy');
}
我还注意到当您打开弹出页面时页面 url 发生了变化,这可能会导致问题并给您Execution context was destroyed
错误...所以您可能必须收集所有链接并在新标签中打开它们
const buttons = document.querySelectorAll('#marketplace-modal-dialog-title');
for await (const b of Array.from(Array(buttons.length).keys())) {
await page.waitForNetworkIdle();
const buttons = document.querySelectorAll('#marketplace-modal-dialog-title');
// do checks before click
await buttons[b].click();
// do checks afer click
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.