2013-05-18 31 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

相關問題