0

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

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

为此,我决定学习抓取,这将我带到了 Cheerio 和 Request。

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

以下是对 / 的 GET 请求调用的路由(请原谅变量名和comments/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();



};

函数 first(); 按预期工作。它将标题、href 和 url 放入数组中的评论中,然后将该数组推送到包含首页上所有帖子的这些数据点的主数组中。然后它调用函数 second();

所述函数的目标是遍历主数组 (mainArr[]),然后选择所有导致评论的 url (mainArr[i][uI]) 并以该 url 作为第一个参数启动 request()。

循环有效,但在 second() 函数内第二次调用 request() 期间,一切都崩溃了。变量 i 永久设置为 -1,commentURL(设置为当前帖子评论 URL 的变量)永久定义为 arrMain[] 中的第一个 url。arrMain.length 也有一些奇怪的行为。根据我放置它的位置,它告诉我 arrMain 未定义。

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

我会非常感谢任何建议!

4

1 回答 1

0

您的猜测是正确的,这是臭名昭著的“Javascript循环陷阱”。例如,请参见此处以获取解释:

Javascript臭名昭著的循环问题?

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

最后,这种语言在 SO 中是不受欢迎的,你最好花 2 分钟在这篇文章中更改你的变量名。

于 2014-02-03T14:23:46.870 回答