javascript - 使用 Puppeteer 抓取多个网站
问题描述
所以我试图只从一个以上的网站(在这种情况下是 PS Store)中只抓取两个元素。另外,我正在尝试以最简单的方式实现它。由于我是 JS 的菜鸟,请保持温和 ;) 在我的脚本下方。我试图用一个 for 循环来实现它,但没有任何效果(它仍然只从数组中获得第一个网站)。非常感谢任何形式的帮助。
const puppeteer = require("puppeteer");
async function scrapeProduct(url) {
const urls = [
"https://store.playstation.com/pl-pl/product/EP9000-CUSA09176_00-DAYSGONECOMPLETE",
"https://store.playstation.com/pl-pl/product/EP9000-CUSA13323_00-GHOSTSHIP0000000",
];
const browser = await puppeteer.launch();
const page = await browser.newPage();
for (i = 0; i < urls.length; i++) {
const url = urls[i];
const promise = page.waitForNavigation({ waitUntil: "networkidle" });
await page.goto(`${url}`);
await promise;
}
const [el] = await page.$x(
"/html/body/div[3]/div/div/div[2]/div/div/div[2]/h2"
);
const txt = await el.getProperty("textContent");
const title = await txt.jsonValue();
const [el2] = await page.$x(
"/html/body/div[3]/div/div/div[2]/div/div/div[1]/div[2]/div[1]/div[1]/h3"
);
const txt2 = await el2.getProperty("textContent");
const price = await txt2.jsonValue();
console.log({ title, price });
browser.close();
}
scrapeProduct();
解决方案
一般来说,您的代码还可以。但是,应该纠正一些事情:
const puppeteer = require("puppeteer");
async function scrapeProduct(url) {
const urls = [
"https://store.playstation.com/pl-pl/product/EP9000-CUSA09176_00-DAYSGONECOMPLETE",
"https://store.playstation.com/pl-pl/product/EP9000-CUSA13323_00-GHOSTSHIP0000000",
];
const browser = await puppeteer.launch({
headless: false
});
for (i = 0; i < urls.length; i++) {
const page = await browser.newPage();
const url = urls[i];
const promise = page.waitForNavigation({
waitUntil: "networkidle2"
});
await page.goto(`${url}`);
await promise;
const [el] = await page.$x(
"/html/body/div[3]/div/div/div[2]/div/div/div[2]/h2"
);
const txt = await el.getProperty("textContent");
const title = await txt.jsonValue();
const [el2] = await page.$x(
"/html/body/div[3]/div/div/div[2]/div/div/div[1]/div[2]/div[1]/div[1]/h3"
);
const txt2 = await el2.getProperty("textContent");
const price = await txt2.jsonValue();
console.log({
title,
price
});
}
browser.close();
}
scrapeProduct();
- 您在循环中打开网页,这是正确的,但随后在循环之外查找元素。为什么?您应该在循环中执行此操作。
- 对于调试,我建议使用
{ headless: false }
. 这使您可以查看浏览器中实际发生的情况。 - 不确定您使用的是哪个版本的 puppeteer,但
networkidle
在最新版本中没有这样的事件npm
。您应该使用networkidle0
ornetworkidle2
代替。 - 您正在通过 xpath 寻找元素
html/body/div...
。这可能是主观的,但我认为标准的 JS/CSS 选择器更具可读性:body > div ...
. 但是,好吧,如果它有效...
在我的情况下,上面的代码产生以下内容:
{ title: 'Days Gone™', price: '289,00 zl' }
{ title: 'Ghost of Tsushima', price: '289,00 zl' }
推荐阅读
- python - Python创建一个与随机生成的列表匹配的列表
- jquery - 从 Scope 中获取 JSON 数据
- import - 将类的实例传递给所有子进程(多处理)以在 spyder 中读取和写入
- python - 使用 UTF8 导出 csv
- c# - 找不到类型。它可能需要装配资格,例如“MyType, MyAssembly”
- javascript - Angular 10从firebase链接下载文件而不打开新标签
- python-3.x - 如何从jsonschema,python3检查数组中的项目
- c++ - C ++ MFC:\ t后菜单中的快捷方式/加速器不出现
- javascript - Cors 策略错误:它没有 HTTP ok 状态
- spring - JWT 令牌的签名无效 - Azure + Spring Boot