cheerio each()函数的行为异常

时间:2018-10-20 21:54:05

标签: javascript node.js web-scraping deployment cheerio

我有一个代码,可以在网页上抓取该页面。我使用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');

         }
     });
 });

先谢谢您! `

1 个答案:

答案 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)