我有一个代码,可以在网页上抓取该页面。我使用puppeteer + cheerio来做到这一点。在我的笔记本电脑上,代码可以完美运行。但是在将其部署到VDS之后,cheerio each()选择器开始奇怪地工作。 (但是在我的笔记本电脑上仍然可以正常使用)。问题是在VDS上发生以下错误:
(节点:28544)UnhandledPromiseRejectionWarning:TypeError:无法读取未定义的属性“ trim” 在节点上。 (/home/ubuntu/handbot/liveMonitoring.js:211:82) 在initialize.exports.each(/home/ubuntu/handbot/node_modules/cheerio/lib/api/traversing.js:300:24) 在节点上。 (/home/ubuntu/handbot/liveMonitoring.js:182:29) 在initialize.exports.each(/home/ubuntu/handbot/node_modules/cheerio/lib/api/traversing.js:300:24) 在liveMonitoring(/home/ubuntu/handbot/liveMonitoring.js:175:28) 在process._tickCallback(内部/进程/next_tick.js:68:7) (节点:28544)UnhandledPromiseRejectionWarning:未处理的承诺被拒绝。引发此错误的原因可能是抛出了一个没有catch块的异步函数,或者是拒绝了一个.catch()无法处理的承诺。 (拒绝ID:1) (节点:28544)[DEP0018] DeprecationWarning:已弃用未处理的承诺拒绝。将来,未处理的承诺拒绝将以非零退出代码终止Node.js进程。
最有趣的一点是有时错误会消失(似乎没有发生错误的模式)。 我试图通过重新安装node js来解决此问题,但此方法不起作用。问题不在我的代码中(因为它可以在我的笔记本电脑上工作,有时甚至可以在vds上工作)。我认为在each()函数的导出中有些东西。由于出现错误消息,因此
/home/ubuntu/handbot/node_modules/cheerio/lib/api/traversing.js:300:24
traversing.js的代码(298-302行):
`
exports.each = function(fn) {
var i = 0, len = this.length;
while (i < len && fn.call(this[i], i,
this[i]) !== false) ++i;
return this;
};
导致错误的代码:
const page = await browser.newPage();
await page.goto(url, {timeout:0}).catch((err)=> { console.log(err)});
await page.setRequestInterception(true);
page.on('request', req => {
if(['image', 'stylesheet', 'font'].indexOf(req.resourceType()) !== -1)
req.abort();
else
req.continue();
});
let content = await page.content();
let $ = cheerio.load(content);
let gameContent=$('#games_content').children('div').children('div');
gameContent.children().each(function(i, elem1){
let league=$(elem1).children('.greenBack').children('.c-events__name').children('a').text().trim();
$(this).children().each(function(j, elem2){
if(j!==0) {
let currentInfo = {};
currentInfo['league'] = league;
let shortCut = $(elem2).children('.c-events__item_game').children('.c-events-scoreboard').children();
let mainInfo = shortCut.first();
currentInfo['link'] = mainInfo.children("a").attr("href");
let teams = mainInfo.children("a").children("span").attr("title").trim().split("—");
currentInfo['team1'] = teams[0].trim();
currentInfo['team2'] = teams[1].trim();
let shortCutForTotal = $(elem2).children('.c-events__item_game').children('.c-bets');
}
});
});
先谢谢您! `
答案 0 :(得分:0)
通过更改以下代码行解决了该问题:
page.on('request', req => {
if(['image', 'stylesheet', 'font'].indexOf(req.resourceType()) !== -1)
req.abort();
else
req.continue();
})
具有以下内容:
page.on('request', interceptedRequest => {
if (interceptedRequest.url().endsWith('.png') || interceptedRequest.url().endsWith('.jpg') || interceptedRequest.url().endsWith('.css'))
interceptedRequest.abort();
else
interceptedRequest.continue();
});
并在上述代码行之后放置await page.goto(url);
。
然后将选项waitUntil:'networkidle0'
添加到page.goto(url)