node.js + cheerio scrape:传递一系列网址下载?

时间:2013-12-13 17:30:02

标签: javascript jquery node.js scrape cheerio

首先,这是我到目前为止进展的代码:

var http = require("http");

// Utility function that downloads a URL and invokes
// callback with the data.
function download(url, callback) {
  http.get(url, function(res) {
    var data = "";
    res.on('data', function (chunk) {
      data += chunk;
    });
    res.on("end", function() {
      callback(data);
    });
  }).on("error", function() {
    callback(null);
  });
}

var cheerio = require("cheerio");

var url = "http://www.bloglovin.com/en/blogs/1/2/all";
var myArray = [];
var a = 0;

var getLinks = function(){download(url, function(data) {
  if (data) {
    // console.log(data);
    var $ = cheerio.load(data);
    $(".content").each(function(i, e) {
      var blogName = $(e).find(".blog-name").text();
      var followLink = $(e).find("a").attr("href");
      var blogSite = $(e).find(".description").text();

      myArray[a] = [a];
      myArray[a]["blogName"] = blogName;
      myArray[a]["followLink"] = "http://www.bloglovin.com"+followLink;
      myArray[a]["blogSite"] = blogSite;

      a++;

      console.log(myArray);

    });
  }
});
}

getLinks();

正如您所看到的,followLinks已连接到followUrl,其中我想通过'url'下载,因此我将有效地抓取每个页面使用相同的CSS规则,这些规则将被添加到相应博主的多维数组中。

我该如何解决这个问题?

3 个答案:

答案 0 :(得分:1)

我在其中一个抓取工作中做了类似的事情,但我使用async.js库来完成。请注意,我在抓取时也使用了request模块和cheerio.js。我从一个网页上获取并抓取数据行,但怀疑你可以采取类似的方式来获取URL并以相同的方式请求/抓取它们。

我也承认这是非常基本的编码,当然可以通过一些重构进行优化。希望它至少给你一些想法...

首先,我使用request来获取页面并调用我的解析函数 -

var url = 'http://www.target-website.com';
function(lastCallback) {
    request(url, function(err, resp, body) {
        if(!err) { parsePage(err, resp, body, lastCallback); }
          else { console.log('web request error:' + resp.statusCode); }
    }
}

接下来,在我的parsePage函数中,我将网站加载到Cheerio,将每个数据行的HTML提取到一个数组中,将我的parseRow函数和每个HTML段推送到另一个数组中,然后使用async.parallel处理每次迭代 -

var rows = [];
function parsePage(err, resp, body, callback1) {
    var $ = cheerio.load(body);
    $('div#targetTable tr').each(function(i, elem) {
        rows.push($(this).html());
    });

    var scrRows = [];
    rows.forEach(function(row) {
        scrRows.push(function(callback2) {
            parseRow(err, resp, row);
            callback2();
    });

    async.parallel(scrRows, function() {
        callback1();
    });
}

答案 1 :(得分:0)

您已定义a = 0;所以

myArray[a] = [a]; // => myArray[0] = [0]; myArray[0] becomes an array with 0 as only member in it

所有这些语句都会抛出错误,因为Array只能将整数作为键。

myArray[a]["blogName"] = blogName;
myArray[a]["followLink"] = "http://www.bloglovin.com"+followLink;
myArray[a]["blogSite"] = blogSite;

而是试试这个:

var obj = { 
  index: a,
  blogName: blogName,
  followLink: "http://www.bloglovin.com" + followLink,
  blogSite: blogSite
}

myArray.push(obj);
console.log(myArray);

答案 2 :(得分:0)

在你的循环中,只需创建一个具有你抓取的属性的对象,然后将该对象推送到你的数组上。

var blogInfo = {
  blogName: blogName,
  followLink: "http://www.bloglovin.com"+followLink;
  blogSite: blogSite
};
myArray.push(blogInfo);