【问题标题】:node.js + cheerio scrape: Passing an array of urls to download?node.js + Cheerio scrape:传递要下载的 URL 数组?
【发布时间】:2013-12-13 17:30:02
【问题描述】:

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

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 规则有效地抓取每个页面,将添加到对应博主的多维数组中。

我该怎么办?

【问题讨论】:

  • 两次调用包含http 模块?请删除其中一个
  • 这是一个粘贴错误!

标签: javascript jquery node.js scrape cheerio


【解决方案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();
    });
}

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 看起来不错。那么,如何使用 followLink 中的 url 来抓取每个单独的页面呢?
    【解决方案3】:

    你已经定义了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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-25
      • 2015-09-15
      • 1970-01-01
      • 1970-01-01
      • 2019-02-25
      • 1970-01-01
      相关资源
      最近更新 更多