0

最初に:私はノードが初めてで、比較的プログラミングの初心者です。

Express を使用して小さな Web アプリを作成しようとしています。その唯一の目標は、オープン API を持たない Web サイトからデータを取得して再フォーマットすることです。

そのためにスクレイピングを学ぼうと思い、チェリオとリクエストにたどり着きました。

学習するために例として 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();



};

関数 first(); 意図したとおりに動作します。配列内のコメントにタイトル、href、および url を配置し、その配列を、フロント ページのすべての投稿のデータ ポイントを含むマスター配列にプッシュします。次に、関数 second() を呼び出します。

この関数の目的は、マスター配列 (mainArr[]) をループしてから、コメントにつながるすべての URL (mainArr[i][uI]) を選択し、その URL を最初のパラメーターとして request() を起動することです。

ループは機能しますが、second() 関数内での request() の 2 回目の呼び出し中に、すべてが機能しなくなります。変数 i は永続的に -1 に設定され、commentURL (現在の投稿のコメントの URL に設定される変数) は arrMain[] の最初の URL として永続的に定義されます。arrMain.length にも奇妙な動作があります。配置場所によっては、arrMain が未定義であることがわかります。

明らかな何かが欠けているような気がしますが (おそらく非同期性と関係があります)、私の人生では、それを見つけることができません。

私はどんな提案にも本当に感謝しています!

4

1 に答える 1