【问题标题】:Nodejs Webscraping function using Cheerio returns before finished使用 Cheerio 的 Nodejs Webscraping 函数在完成之前返回
【发布时间】:2020-03-22 02:38:50
【问题描述】:

我目前正在开发一个简单的网络抓取 nodejs 程序。它基于cheerio,我从一个网站获取项目并从那里提取一些信息。

据我了解,我在 foreach 循环中调用的所有函数都是同步的,因此它们应该从上到下执行。而且因为foreach循环也只是一个普通的循环,它在js中执行同步,所以该函数应该返回我完成的数组。但相反,它变得未定义,当我将它直接登录到控制台时它可以工作(?)。

function getIntensiv(){
    var intensivregister = [];
    request.post({url: 'SOMEURL', form: {SOMEFORM}}, function(err,res,body){
        var $ = cheerio.load(body);
        $('#dataList').children('tbody').children('tr').each(function(i, elem){
            var name = $(elem).children('td').first().text().trim().split("\n")[0].trim();                        
            var zipcity = $(elem).children('td').first().children('small').last().text();                         
            var streetnr = $(elem).children('td').first().children('br').last().prev().text();                    
            intensivregister.push({'name': name, 'zipcity': zipcity, 'streetnr': streetnr});
        });
        console.log(intensivregister);  //works and prints the finished array
        return intensivregister;        //returns undefined before function finished
    });
}

如果你能解释我的错误在哪里并帮助我解决它,我将不胜感激。

【问题讨论】:

  • 你从 request.post 回调中返回了一些东西。函数本身不返回任何内容。

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


【解决方案1】:
function getIntensiv(){
const cheerio = require('cheerio')
const request = require('request')

var intensivregister = [];
request.get({url: 'https://www.w3schools.com/html/html_tables.asp'}, function(err,res,body){


var $ = cheerio.load(body);

    $('#customers').children('tbody').children('tr').each(function(i, elem){
        var name = $(elem).children('td').first().text().trim().split("\n")[0].trim();                        
        var zipcity = $(elem).children('td').first().children('small').last().text();                         
        var streetnr = $(elem).children('td').first().children('br').last().prev().text();                    
        intensivregister.push({'name': name, 'zipcity': zipcity, 'streetnr': streetnr});
    });
    console.log(intensivregister);  //works and prints the finished array
    return null;        //returns undefined before function finished
});
return null;   //***<---This is returning and not the above return. If no return statement is written then undefined is passed.***
};

var retrunVal = getIntensiv()
console.log(retrunVal);

请找到突出显示的评论

【讨论】:

  • 我现在使用了第二个返回,但我的数组是空的,所以显然它在 request.post 完成填充我的数组之前返回...
【解决方案2】:

好吧,我发现我对 javascript 的想法不是你应该如何使用它。我解决了我的问题,摆脱了从函数返回值的想法(这主要来自我在异步编程中的经验),而是使用我给函数并在请求结束时调用的回调参数。

function getIntensiv(callback){
    var intensivregister = [];
    request.post(...);
    **callback(intensivregister);**
}

还有什么在起作用(我认为一个更好的解决方案)正在使用承诺,例如使用 request-promise 并在 finally 调用中调用回调。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-23
    • 1970-01-01
    • 2020-09-26
    • 1970-01-01
    • 2017-09-30
    相关资源
    最近更新 更多