我正在嘗試從 ebay 獲取產品并在亞馬遜上打開它們。
到目前為止,我已經在亞馬遜上搜索它們,但我正在努力從搜索結果中選擇產品。
目前它輸出一個空白陣列,我不知道為什么。已經在沒有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:jmp_supplies|folenttp:1&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)
}
})()
uj5u.com熱心網友回復:
該腳本存在一些潛在問題:
await page.keyboard.press('Enter');觸發導航,但您的代碼在嘗試選擇結果元素之前從不等待導航完成。使用waitForNavigation,waitForSelector或waitForFunction(不是waitForTimeout)。如果您確實等待導航,則需要使用一種特殊的模式
Promise.all來避免競爭條件,如docs所示。此外,您可以通過自己構建字串直接進入搜索 URL 來跳過頁面加載。這應該提供顯著的加速。
您的代碼為需要處理的每個專案生成一個新頁面,但這些頁面永遠不會關閉。我看到
grabTitles.length60。所以你將打開 60 個標簽。這是浪費了很多資源。在我的機器上,它可能會掛起所有東西。我建議制作一個頁面并重復導航,或者在完成后關閉每個頁面。如果您想要并行性,請考慮使用任務佇列或同時運行幾頁。grabTitles[i ]——為什么要i在這里增加?它已經被回圈遞增了,所以這似乎跳過了元素,除非你的選擇器有重復或者你有其他理由這樣做。span.a-size-medium對我不起作用,這可能是特定于地方的。我明白a span.a-size-base-plus.a-color-base.a-text-normal了,但你可能需要調整它的味道。
這是一個最小的例子。我將只做 eBay 陣列中的前 2 個專案,因為這很好。
const puppeteer = require("puppeteer"); // ^13.5.1
let browser;
(async () => {
browser = await puppeteer.launch({headless: true});
const [page] = await browser.pages();
const ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36";
await page.setExtraHTTPHeaders({"Accept-Language": "en-US,en;q=0.9"});
await page.setUserAgent(ua);
const titles = [
"Chloraethyl | Dr. Henning | Spray 175 ml",
"Elmex Decays Prevention Toothpaste 2 x 75ml",
];
for (const title of titles) {
await page.goto("https://www.amazon.co.uk/");
await page.type("#twotabsearchtextbox", title);
await Promise.all([
page.keyboard.press("Enter"),
page.waitForNavigation(),
]);
const titleSel = "a span.a-size-base-plus.a-color-base.a-text-normal";
await page.waitForSelector(titleSel);
const results = await page.$$eval(titleSel, els =>
els.map(el => el.textContent)
);
console.log(title, results.slice(0, 5));
}
})()
.catch(err => console.error(err))
.finally(() => browser?.close())
;
輸出:
Chloraethyl | Dr. Henning | Spray 175 ml [
'Chloraethyl | Dr. Henning | Spray 175 ml',
'Wild Fire (Shetland)',
'A Dark Sin: A chilling British detective crime thriller (The Hidden Norfolk Murder Mystery Series Book 8)',
'A POLICE DOCTOR INVESTIGATES: the Sussex murder mysteries (books 1-3)',
'Rites of Spring: Sunday Times Crime Book of the Month (Seasons Quartet)'
]
Elmex Decays Prevention Toothpaste 2 x 75ml [
'Janina Ultra White Whitening Toothpaste (75ml) – Diamond Formula. Extra Strength. Clinically Proven. Low Abrasion. For Everyday Use. Excellent for Stain Removal',
'Elmex Decays Prevention Toothpaste 2 x 75ml',
'Elmex Decays Prevention Toothpaste 2 x 75ml by Elmex',
'Elmex Junior Toothpaste 2 x 75ml',
'Elmex Sensitive Professional 2 x 75ml'
]
請注意,我添加了用戶代理和標頭以便能夠使用headless: true,但它是上述主要解決方案的附帶條件。您可以回傳headless: false或查看規范執行緒,例如如何避免在 Puppeteer 和 Phantomjs 上被檢測為機器人?以及為什么 Puppeteer 需要為假的 headless 才能作業?如果您在檢測方面還有其他問題。
uj5u.com熱心網友回復:
您已經遇到了 Puppeteer 的一個古老問題,并且知道頁面何時完全完成渲染或加載。
您可以嘗試添加以下內容:
await page.waitForNavigation({ waitUntil: 'networkidle2' })
await page.waitForTimeout(10000)
通常我發現networkidle2它并不總是足夠可靠,所以我添加了一個任意額外的waitForTimeout. 您需要使用超時值(10000 = 10 秒)來獲得您正在尋找的東西,我知道這并不理想,但我還沒有找到更好的方法。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/455133.html
標籤:javascript 节点.js 网络 网页抓取 傀儡师
