如何在PhantomJS中使用jQuery循环表行

时间:2015-07-09 18:13:03

标签: jquery node.js loops web-scraping phantomjs

我正在尝试使用node.js学习一些网页抓取。我选择了一些示例页面,例如http://www.imdb.com/chart/top。然后我试图用评级来刮掉所有头衔。我创建了一个PhantomJS脚本(我需要使用它,因为它是动态的,所以它在网站上使用JavaScript)。它工作正常,但我不知道如何为每个标题制作一个循环。

例如:

$('.lister-list tr').each(
  function(){
    $(this).find('.titleColumn').text().replace(/\n/g, '');
    $(this).find('.imdbRating').text().replace(/\n/g, '');
  }
);

然后我把它全部放在一个JSON文件中。此时我只能在没有循环的情况下放入数据。这是我的剧本:

var phantom = require('phantom');
var fs = require('fs');

phantom.create(function (ph) {
  ph.createPage(function (page) {
    page.open("http://www.imdb.com/chart/top", function (status) {
      page.evaluate(function () {

        //search datajquer
        var k_title = $('.lister-list tr .titleColumn').first().text().replace(/\n/g, '');
        var k_rating = $('.lister-list tr .imdbRating').first().text().replace(/\n/g, '');

        // create json data
        var metadata = JSON.stringify({
          Title: k_title,
          Rating: k_rating
        });

        return metadata; 

      }

        , function (result) {
        //save json data
        fs.appendFile('java.json', "\n" + result, function (err) {
          if (err) throw err;
          console.log('file is updated!');
        });
        //display data in console
        console.log('Result: ' + result);
        ph.exit();
        });
    });
  });
});

如何制作一个循环遍历所有TR元素的循环?

1 个答案:

答案 0 :(得分:2)

你需要的是一个阵列。您可以初始化一个空数组并将新对象推送到它上面,如下所示:

page.evaluate(function () {
    var metadataList = [];
    $('.lister-list tr').each(function(){
        var metadata = {
            Title: $(this).find('.titleColumn').text().replace(/\n/g, ''),
            Rating: $(this).find('.imdbRating').text().replace(/\n/g, '')
        };
        metadataList.push(metadata);
    });

    return JSON.stringify(metadataList);
}, function(result){ ... });

你也可以使用jQuery map()函数将每一行映射到一个对象并以这种方式创建一个数组:

page.evaluate(function () {
    var metadataList = $('.lister-list tr').map(function(){
        return {
            Title: $(this).find('.titleColumn').text().replace(/\n/g, ''),
            Rating: $(this).find('.imdbRating').text().replace(/\n/g, '')
        };
    }).get();

    return JSON.stringify(metadataList);
}, function(result){ ... });

请注意,必须在get()结果上调用map()来检索实际数组,而不是jQuery对象。

您不需要jQuery来执行此操作:

page.evaluate(function () {
    var metadataList = [];
    [].forEach.call(document.querySelectorAll('.lister-list tr'), function(tr){
        var metadata = {
            Title: tr.querySelector('.titleColumn').textContent.replace(/\n/g, ''),
            Rating: tr.querySelector('.imdbRating').textContent.replace(/\n/g, '')
        };
        metadataList.push(metadata);
    });

    return JSON.stringify(metadataList);
}, function(result){ ... });