javascript - 在 Puppeteer 中循环一组 url
问题描述
如何使用 Puppeteer 从多个 url 中抓取内容?
我创建了一个循环,但我只看到第一个 url 的结果。
我怀疑这与我声明结果变量的位置有关,但我没有运气尝试,有人知道该怎么做吗?
const puppeteer = require('puppeteer');
function run() {
return new Promise(async (resolve, reject) => {
try {
const browser = await puppeteer.launch();
const page = await browser.newPage();
const urls = ["https://www.marksandspencer.com/high-neck-long-sleeve-blouse/p/p60260040?image=SD_01_T43_5168_HD_X_EC_90&color=LIGHTDENIM&prevPage=plp", "https://www.marksandspencer.com/pure-cotton-printed-short-sleeve-t-shirt/p/p60263529?image=SD_01_T41_8030Z_Z4_X_EC_90&color=WHITEMIX&prevPage=plp"];
for (let i = 0; i < urls.length; i++) {
const url = urls[i];
await page.goto(url);
let products = await page.evaluate(() => {
let product = document.querySelector('h1[itemprop=name]').innerText;
let results = [];
let items = document.querySelectorAll('[data-ttip-id=sizeGridTooltip] tbody tr td label');
items.forEach((element) => {
let size = element.getAttribute('for');
let stockLevel = "";
let nearest_td = element.closest('td');
if (nearest_td.classList.contains('low-stock')) {
stockLevel = "Low stock"
} else if (nearest_td.classList.contains('out-of-stock')) {
stockLevel = "Out of stock"
} else {
stockLevel = "In stock"
}
results.push({
product: product,
size: size,
stock: stockLevel
})
});
return results
})
browser.close();
return resolve(products);
}
} catch (e) {
return reject(e);
}
})
}
run().then(console.log).catch(console.error);
解决方案
这些行在您的 for 循环中:
browser.close();
return resolve(products);
因此,作为第一次迭代的一部分,您关闭浏览器并返回函数。您应该将其移出 for 循环并存储products
在这样的数组中:
const urls = /* ... */;
const productsList = [];
for (let i = 0; i < urls.length; i++) {
const url = urls[i];
await page.goto(url);
let products = await page.evaluate(/* ... */);
productsList.push(products);
}
browser.close();
return resolve(productsList); // resolve with an array containing the aggregated products
如果您正在寻找更优雅的解决方案(用于并行抓取页面),您可能需要查看puppeteer-cluster库(免责声明:我是作者)。
推荐阅读
- bash - 从 Dockerfile 执行 Shell 脚本
- networking - 来自远程 ip 的数据包如何到达本地进程
- woocommerce - 取消设置后如何恢复woocommerce结帐字段
- docker - 是否可以定义在 k8s 和 docker 中都可用的卷?
- java - javax.net.ssl.sslhandshakeexception 华为手机握手失败
- javascript - 将大型 koa 请求正文上传到 AWS S3 的正确方法是什么?
- android - code keeps running without proper sequence
- java - java - 如何在java中每x秒执行一个方法y时间
- c - 缺少头文件,
对于ANSI C? - python - 变量更改时,引用变量的 Tkinter 标签不会更新