如何在json nodejs中保存带有请求的文件?

时间:2013-05-18 20:18:31

标签: node.js

我正在尝试将结果保存到json文件中,但是当我看到它变成了一半时,我的代码中出现了一些错误,但是我不明白你的问题,谢谢你的帮助。

var request = require("request");
var cheerio = require("cheerio");
var fs = require('fs');
var urls = ["http://www.fordencuotas.com.ar"]

var req = function(url){
    request({
        uri: url,
    }, function(error, response, body) {
        var $ = cheerio.load(body);
        $("a").each(function() {
        var link = $(this);
        var itri = {iti: new Array(link.attr("href"))}
        var data = JSON.stringify(itri);
        fs.writeFile("file.json", data, function(err){
            if(err){console.log(err);} else {console.log("archivo guardado..");}
        });
        });
    });
}

for (var i = 0; i < urls.length; i++){
    req(urls[i]);
}

console.log("cargando...");

此输出

[opmeitle@localhost crawler1]$ node crawmod.js
cargando...
archivo guardado..
archivo guardado..
archivo guardado..
archivo guardado..
archivo guardado..
...
archivo guardado..
[opmeitle@localhost crawler1]$ cat file.json
{"iti":["productos/autos/nuevo-focus.html"]}us.html"]}
[opmeitle@localhost crawler1]$ 

1 个答案:

答案 0 :(得分:4)

您的代码中存在一些问题。

首先,您尝试为每个file.json元素覆盖相同的文件(a)。我不确定这是不是你的意图,但似乎毫无意义。

其次,fs.writeFile是异步的。这意味着Node在返回循环之前不会等到文件被写入。换句话说,对于每个a元素,您打开相同的文件,而它可能已经被循环的早期迭代打开。每次迭代都会写入同一个文件,因此您最终会得到意想不到的结果。

您可以使用fs.writeFileSync同步写入文件,这会使Node等待,直到数据在继续之前写入文件,或者将要保存的所有数据收集到变量中的文件中,以及 - 在$("a").each(...)循环之后 - 只将该变量写入文件一次。

最后一个解决方案看起来像这样:

var data = [];
$("a").each(function() { 
  var link = $(this);
  var itri = {iti: new Array(link.attr("href"))}
  data.push( itri );
});
fs.writeFile("file.json", JSON.stringify(data), function(err){
  if(err){console.log(err);} else {console.log("archivo guardado..");}
});