我正在构建一个Ebay web scraper作为一个辅助项目,我需要知道如何多次调用基于promise的函数,以在多个页面上获取卖家的所有物品,直到我到达他的物品的末尾。
基本上,使用Javascript和Node.js,如果卖家只有1页的商品,我会把它刮下来,一切都很好。
当他有多个页面时,事情对我来说会变得复杂,我需要多次调用promise函数并返回每个页面的链接。我尝试过promise循环,我尝试过递归,我也尝试过async/await。似乎什么都不管用。
我将为你们提供一个代码片段:
const request = require('request-promise');
const cheerio = require('cheerio');
const options = {
url : 'https://www.ebay.com/sch/i.html?_nkw=&_in_kw=1&_ex_kw=&_sacat=0&_udlo=&_udhi=&_ftrt=901&_ftrv=1&_sabdlo=&_sabdhi=&_samilow=&_samihi=&_sadis=15&_stpos=29582&_sargn=-1%26saslc%3D1&_salic=1&_fss=1&_fsradio=%26LH_SpecificSeller%3D1&_saslop=1&_sasl=brickearth&_sop=12&_dmd=1&_ipg=50&_fosrp=1',
//url : 'https://www.ebay.com/sch/i.html?_nkw=&_in_kw=1&_ex_kw=&_sacat=0&_udlo=&_udhi=&_ftrt=901&_ftrv=1&_sabdlo=&_sabdhi=&_samilow=&_samihi=&_sadis=15&_stpos=29582&_sargn=-1%26saslc%3D1&_salic=1&_fss=1&_fsradio=%26LH_SpecificSeller%3D1&_saslop=1&_sasl=supersavingsdeals&_sop=12&_dmd=1&_ipg=200&_fosrp=1',
method : 'GET',
headers : {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
}
}
const pageLinks = [];
async function getPagesRecursive(link) {
await request(link, (error, response, html) => {
if(!error && response.statusCode === 200) {
const $ = cheerio.load(html);
const nextPage = $('td.pagn-next > a').attr('href');
pageLinks.push(link)
if(nextPage) {
return getPagesRecursive(nextPage);
}
console.log(pageLinks);
}
})
}
我敢肯定,这对Javascript和Node.js专家来说毫无意义;)我已经用async/await把它发布给你了,但我想在请求模块中使用promise,因为我觉得我更了解它们,而且就我个人而言,我已经尝试了所有其他方法,但都没有成功:)
我已经为你们提供了两个url来尝试请求模块的选项对象。第一个是一个链接到一个卖家的多个项目,它应该得到所有的页面链接。第二个链接是一个只有一个页面的卖家,它应该只得到该卖家的一个页面链接。
提前感谢您;)
request
返回promise时,不需要使用回调,也不需要使用async
await
语法,只需返回promise即可。
此外,与其填充全局pageLinks
数组,不如根据promise实现的值构建链接数组。
function getPagesRecursive(link) {
return request(link).then(html => {
const $ = cheerio.load(html);
const nextPage = $('td.pagn-next > a').attr('href');
return nextPage ? getPagesRecursive(nextPage).then(links => [link, ...links])
: [link];
});
}
// Use:
getPagesRecursive(firstPage).then(links => console.log(links))
.catch(err => console.log("request failed", err));