我试图从ebay上抓取产品,然后在amazon上打开它们。
到目前为止,我已经在亚马逊上搜索了它们,但我很难从搜索结果中选择产品。
目前它输出一个空白数组,我不知道为什么。在没有grabTitles和for循环的单独脚本中进行了测试。所以我猜这里面有什么东西引起了一个问题。
是否有什么我错过了这里,这阻止了数据回来的prodResults?
const puppeteer = require('puppeteer');
const URL = "https://www.amazon.co.uk/";
const selectors = {
searchBox: '#twotabsearchtextbox',
productLinks: 'span.a-size-base-plus.a-color-base.a-text-normal',
productTitle: '#productTitle'
};
(async() => {
const browser = await puppeteer.launch({
headless: false
});
const page = await browser.newPage();
await page.goto('https://www.ebay.co.uk/sch/jmp_supplies/m.html?_trkparms=folent%3Ajmp_supplies%7Cfolenttp%3A1&rt=nc&_trksid=p2046732.m1684');
//Get product titles from ebay
const grabTitles = await page.evaluate(() => {
const itemTitles = document.querySelectorAll('#e1-11 > #ResultSetItems > #ListViewInner > li > .lvtitle > .vip');
var items = []
itemTitles.forEach((tag) => {
items.push(tag.innerText)
})
return items
})
//Search for the products on amazon in a new tab for each product
for (i = 0; i < grabTitles.length; i++) {
const page = await browser.newPage();
await page.goto(URL)
await page.type(selectors.searchBox, grabTitles[i++])
await page.keyboard.press('Enter');
//get product titles from amazon search results
const prodResults = await page.evaluate(() => {
const prodTitles = document.querySelectorAll('span.a-size-medium.a-color-base.a-text-normal');
let results = []
prodTitles.forEach((tag) => {
results.push(tag.innerText)
})
return results
})
console.log(prodResults)
}
})()
2条答案
按热度按时间jrcvhitl1#
该脚本存在一些潜在问题:
await page.keyboard.press('Enter');
触发一个导航,但是您的代码在尝试选择结果元素之前从不等待导航完成。使用waitForNavigation
、waitForSelector
或waitForFunction
(而不是waitForTimeout
)。如果您确实在等待导航,则需要使用
Promise.all
的特殊模式来避免竞争条件,如here所示。此外,您可以通过自己构建字符串直接转到搜索URL来跳过页面加载。这应该提供显著的加速。
1.您的代码会为需要处理的每个项生成一个新页面,但这些页面永远不会关闭。我把
grabTitles.length
看成60。所以你要打开60个标签。这是一个很大的资源浪费。在我的机器上,它可能会挂起一切。我建议制作一个页面并重复导航,或者在完成后关闭每个页面。如果需要并行性,请考虑任务队列或同时运行几个页面。grabTitles[i++]
--为什么在这里增加i
?它已经被循环递增了,所以这看起来像是跳过了元素,除非你的选择器有重复的,或者你有其他的理由这样做。span.a-size-medium
对我不起作用,这可能是特定于本地的。我看到了a span.a-size-base-plus.a-color-base.a-text-normal
,但你可能需要调整一下。这里有一个最小的例子。我只做前2个项目从易趣阵列,因为这是未来通过罚款。
输出:
请注意,我添加了用户代理和头文件,以便能够使用
headless: true
,但这是上面的主要解决方案附带的。您可以返回headless: false
或查看像How to avoid being detected as bot on Puppeteer and Phantomjs?和为什么无头需要为假 puppet 工作的规范线程?如果你有进一步的问题与检测。xnifntxz2#
您遇到了Puppeteer的一个老问题,知道页面何时完全完成渲染或加载。
您可以尝试添加以下内容:
通常我发现
networkidle2
并不总是足够可靠,所以我添加了一个任意的waitForTimeout
。你需要使用超时值(10000 = 10秒)来获得你想要的东西,我知道这不是理想的,但我还没有找到更好的方法。