当前位置: 首页 > 知识库问答 >
问题:

node.js:使用请求和Cheerio问题进行清理

海信鸥
2023-03-14

首先:我是node的新手,也是编程的初学者。

我正在尝试用Express创建一个小型web应用程序,其唯一目标是从一个没有开放API的网站获取并重新格式化数据。

为了做到这一点,我决定学习刮痧,这把我带到了Cheerio和Request。

我以reddit为例来学习。本例的最终目标是收集首页上帖子的名称和href以及指向评论的url,然后进入该页面以刮取评论的数量。

下面是在GET请求中调用到/的路由(请原谅变量名和注释/console.logs,我很失望):

/*
 * GET home page.
 */

exports.index = function(req, res){
  var request = require('request')
   ,  cheerio =require('cheerio')
   ,  mainArr = []
   ,  test = "test"
   ,  uI
   ,  commentURL;


  function first() {
    request("http://www.reddit.com", function(err, resp, body) {
        if (!err && resp.statusCode == 200) {
            var $ = cheerio.load(body);
            $('.thing', '#siteTable').each(function(){
                var url = $('a.title', this).attr('href')
                 ,  title = $('a.title', this).html()
                 ,  commentsLink = $('a.comments', this).attr('href')
                 ,  arr = [];

                arr.push(title);
                arr.push(url);
                arr.push(commentsLink);

                mainArr.push(arr);

            });
            second();
        };
    });
  }

  function second() {
    for (i = mainArr.length - 1; i >= 0; i--) {
        uI = mainArr[i].length - 1;
        commentURL = mainArr[i][uI];
        console.log(commentURL + ", " + uI + ", " + i);

        var foo = commentURL;

        request(foo, function(err, resp, body) {
            console.log("what the shit");
            // var $ = cheerio.load(body);
            // console.log(mainArr.length + ", " + commentURL + ", " + i + ", " + uI);
            // var test = $('span.title', 'div.content').html();
            console.log(test + ", "+ foo + ", " + commentURL + ", " + i + ", " + uI);
            // mainArr[1][2] = test;

        });
    };
    if (i<=0) {
        res.render('index', {title: test});
    };

  }

   first();



};

函数第一();按预期工作。它将标题、href和注释的url放在一个数组中,然后将该数组推送到包含首页上所有帖子的数据点的主数组中。然后调用函数second();

所述函数的目标是遍历主数组(mainarr[]),然后选择所有指向注释的url(mainarr[i][uI]),并以该url作为第一个参数启动请求()。

该循环工作,但是在第二次调用request()函数内部的过程中,一切都崩溃了。我得到的变量被永久设置为-1,而commentURL(被设置为当前帖子的注释的URL的变量)被永久定义为arrmain[]中的第一个URL。还有一些带有arrmain.length的怪异行为。根据我放置它的位置,它告诉我arrMain是未定义的。

我有一种感觉,我错过了一些明显的东西(可能与异步性有关),但我一辈子都找不到它。

我会非常乐意为任何建议!

共有1个答案

施慈
2023-03-14

您的猜测是正确的,这就是臭名昭著的“JavaScript循环gotcha”。例如,请参见此处的解释:

Javascript臭名昭著的循环问题?

除此之外,似乎只有您的调试打印受到影响。关于var test的注释代码应该可以工作。

最后,这种语言是不受欢迎的,所以,在这篇文章中,您最好花两分钟时间更改变量名。

 类似资料:
  • 问题内容: 我有以下Node.js代码: 现在,如果我发布类似的内容: 我得到了预期的结果。现在,如果我想获得完整的请求正文怎么办?我尝试这样做,但是Node.js抛出一个异常,说“ 第一个参数必须是字符串或Buffer ”,然后转到“无限循环”,并出现异常,指出“ 发送标头后不能设置标头 ”。即使我再写了也是这样。 这里有什么问题? 另外,我可以不使用而直接获得原始请求吗? 问题答案: Expr

  • 本文向大家介绍node.js中的favicon.ico请求问题处理,包括了node.js中的favicon.ico请求问题处理的使用技巧和注意事项,需要的朋友参考一下 这样的代码在请求时会出现两条请求: 第一条时URL地址为用户输入的客户端请求的目标URL地址,"/"代表用户的目标url地址为web应用程序的根目录. 第二个目标URL地址问浏览器为页面在收藏夹中的显示图标.默认为favicon.i

  • 问题内容: 我在使用redis和nodejs时遇到问题。我必须遍历电话号码列表,并检查我的Redis数据库中是否存在该号码。这是我的代码: “之后”控制台日志出现在“之前”控制台日志之前,并且回调始终返回一个empty 。这是因为如果我很了解,对redis的请求是异步的。但问题是我不知道如何使它起作用。我能怎么做 ? 问题答案: 您有两个主要问题。 您的变量将不是您想要的变量。可以通过更改 数组的

  • 我正在尝试对put请求进行测试,它给了我空指针错误,只是在这种类型的请求中,我不知道为什么请有人帮我,这是我的控制器: 对于测试方法:

  • 我的问题: 我正在构建一个包含Cheerio、Node.js和Google Cloud功能的Web刮板。 问题是我需要发出多个请求,然后在调用response.send()并因此终止函数之前将每个请求中的数据写入Firestore数据库。 我的代码需要两个循环:第一个循环使用我db中的URL,每个URL都发出一个单独的请求。第二个循环是Cheerio使用.each从DOM中刮取多行表数据,并对每一

  • 问题内容: 我正在尝试使用请求获取正确的编码。 不管我做什么,丹麦字符的编码都不对。 有什么想法吗? 问题答案: 也许您的麻烦在于标题。假设您的标题为 如果是这样,您有2种方法可以解决此问题: 删除此标题 使用以下代码解压缩数据: });