Node.js:使用Request和Cheerio问题进行抓取

时间:2014-02-03 11:45:43

标签: javascript node.js request screen-scraping cheerio

首先关闭:我是节点新手,也是相对编程初学者。

我正在尝试使用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未定义。

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

我对任何建议都非常满意!

1 个答案:

答案 0 :(得分:0)

你猜对了,这是臭名昭着的“Javascript循环问题”。例如,请参阅此处,以获得解释:

Javascript infamous Loop issue?

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

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