2

我正在尝试将结果保存到 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]$ 
4

1 回答 1

4

您的代码中有几个问题。

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

其次,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..");}
});
于 2013-05-18T20:37:20.220 回答