Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Json 如何写入和立即读取文件nodeJS_Json_Node.js_Web Scraping - Fatal编程技术网

Json 如何写入和立即读取文件nodeJS

Json 如何写入和立即读取文件nodeJS,json,node.js,web-scraping,Json,Node.js,Web Scraping,我必须获得一个json,该json在某个页面的脚本标记中不受信任。。。所以我不能使用常规的刮削技术,比如cheerio。 简单的解决方法是,将文件(下载页面)写入服务器,然后使用字符串操作读取,以提取json(有几个)并保存到数据库中 问题是我对nodeJS太陌生了,无法让代码正常工作,我想我正在尝试在文件完全写入之前读取它,如果在获取[Object]之前读取它一段时间 这是我到目前为止所拥有的 var http = require('http'); var fs = require('fs'

我必须获得一个json,该json在某个页面的脚本标记中不受信任。。。所以我不能使用常规的刮削技术,比如cheerio。 简单的解决方法是,将文件(下载页面)写入服务器,然后使用字符串操作读取,以提取json(有几个)并保存到数据库中

问题是我对nodeJS太陌生了,无法让代码正常工作,我想我正在尝试在文件完全写入之前读取它,如果在获取[Object]之前读取它一段时间

这是我到目前为止所拥有的

var http = require('http');

var fs = require('fs');
var request = require('request');

var localFile = 'tmp/scraped_site_.html';
var url = "siteToBeScraped.com/?searchTerm=foobar"

// writing
var file = fs.createWriteStream(localFile);

var request = http.get(url, function(response) {
    response.pipe(file);
});

//reading
var readedInfo = fs.readFileSync(localFile, function (err, content) {
    callback(url, localFile);
    console.log("READING: " + localFile);
    console.log(err);
});
根据帮助,“get”不返回响应体

这是根据同一页面上的请求示例修改的

您需要做的是处理传入http.request的回调(函数)中的响应,以便在准备就绪时调用它(异步)


编辑 我更新了示例,以便在创建文件后读取该文件。这是通过在响应的结束事件上有一个回调来实现的,该回调关闭管道,然后可以重新打开文件进行读取。或者,您可以使用

 req.on('data', function(chunk){...})

在数据到达时对其进行处理,而不将其放入临时文件

因此,首先,我认为您应该了解出了什么问题

http请求操作是异步的。这意味着http.get()中的回调代码将在将来某个时候运行,但是fs.readFileSync由于其同步性质,甚至在http请求实际发送到将执行它的后台线程之前就将执行并完成,因为它们都是在通常称为(相同)的勾号中调用的。另外,fs.readFileSync返回一个值,不使用回调

即使将fs.readFileSync替换为fs.readFile,代码仍可能无法正常工作,因为readFile操作可能在http响应从套接字完全读取并写入磁盘之前执行

我强烈建议阅读:和/或

调用文件读取的正确位置是当响应流完成写入文件时,如下所示:

var request = http.get(url, function(response) {
    response.pipe(file);
    file.once('finish', function () {            
        fs.readFile(localFile, /* fill encoding here */, function(err, data) {
            // do something with the data if there is no error
        });         
    });
});
http.request('u/r/l',function(res){
   res.on('data',function(data){
      //parse data as it comes in
   }
});
当然,这是一种非常原始且不推荐的编写异步代码的方法,但这完全是另一种讨论

话虽如此,如果您下载一个文件,将其写入磁盘,然后将其全部读回内存进行操作,那么您最好放弃文件部分,直接将响应读入字符串。然后,您的代码看起来是这样的(这可以通过多种方式实现):

IMO真正应该做的是创建一个转换流,它将从响应中删除所有需要的数据,同时不消耗太多内存,并生成外观更优雅的代码:

var request = http.get(url, function(response) {
    response.pipe(yourTransformStream).pipe(file)
});
然而,实现这个转换流可能会稍微复杂一些。因此,如果您是节点初学者,并且不打算下载大文件或大量小文件,那么将整个内容加载到内存中并对其执行字符串操作可能会更简单

有关转换流的更多信息:

  • 这是子堆栈
  • 来自strongloop

最后,看看你是否可以使用已经存在的百万node.js爬虫中的任何一个:-)看一看npm

我的印象是,你通过从下载包含HTML的文件的流中读取js对象,将其序列化为JSON。这是可以做到但很难做到的。很难知道搜索表达式是何时找到的,因为如果在块进入时进行解析,则永远不知道是否只接收到上下文,也永远无法找到所要查找的内容,因为它被分为两个或多个部分,从未作为一个整体进行过分析

您可以尝试以下方法:

var request = http.get(url, function(response) {
    response.pipe(file);
    file.once('finish', function () {            
        fs.readFile(localFile, /* fill encoding here */, function(err, data) {
            // do something with the data if there is no error
        });         
    });
});
http.request('u/r/l',function(res){
   res.on('data',function(data){
      //parse data as it comes in
   }
});

这允许您在数据进入时读取数据。如果您将脚本标记中的内容累积为单个字符串,然后在其中解析对象,则可以将其保存到光盘、数据库,甚至可以对其进行解析。

没有足够的时间提供正式且经过测试的答案,但您是对的。听一听file.on('finished',function(){}),看谢谢,我花了两天时间阅读了你给我指出的内容,我觉得我走错了方向。。。