2013-05-18 34 views
2

我试图将结果保存到json文件,但是当我看到它变成了一半时,在我的代码中发生了这样的错误,但我不明白你是否属于,谢谢你的帮助。如何在json nodejs中用请求保存文件?

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..."); 

这个输出

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

回答

4

有一个在你的代码中的几个问题。

首先,您要覆盖每个a元素相同的文件(file.json)。我不确定这是你的意图,但它似乎没有意义。

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

您可以使用fs.writeFileSync来同步写入文件,这会使节点等待,直到数据在继续之前写入文件,或者收集想要保存到文件中的所有数据到变量中,并且 - 在$("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..");} 
}); 
+0

首先,感谢您的简单的解释,我可以用你的榜样正确解析 - 感谢你的帮助 – opmeitle

相关问题