Node.js 使用Nodejs/Papa Parse解析远程CSV文件?

Node.js 使用Nodejs/Papa Parse解析远程CSV文件?,node.js,csv,parsing,papaparse,Node.js,Csv,Parsing,Papaparse,我目前正在解析来自节点应用程序的远程csv产品提要,并希望使用Papa Parse来完成这项工作(因为我过去在浏览器中已经成功地使用了Papa Parse) Papa Parse Github: 我最初的尝试和网络搜索并没有找到具体的方法。Papa自述文件说Papa解析现在与Node兼容,因此Baby Parse(用于提供一些节点解析功能)被贬低了 这里有一个指向文档节点部分的链接,供将来遇到此问题时使用: 从那个文档段落来看,papaparse-in节点似乎可以解析可读的流而不是文件。我的问题

我目前正在解析来自节点应用程序的远程csv产品提要,并希望使用Papa Parse来完成这项工作(因为我过去在浏览器中已经成功地使用了Papa Parse)

Papa Parse Github:

我最初的尝试和网络搜索并没有找到具体的方法。Papa自述文件说Papa解析现在与Node兼容,因此Baby Parse(用于提供一些节点解析功能)被贬低了

这里有一个指向文档节点部分的链接,供将来遇到此问题时使用:

从那个文档段落来看,papaparse-in节点似乎可以解析可读的流而不是文件。我的问题是,

是否有任何方法可以利用可读流功能使用Papa下载/解析节点中的远程CSV?类似于浏览器中的Papa如何使用XMLHttpRequest来实现相同的目标

用于未来的可见性 对于在主题上搜索(并避免重复类似问题)的用户,尝试利用此处描述的远程文件解析功能:将在控制台中导致以下错误:

“未处理的拒绝引用错误:未定义XMLHttpRequest”

我已在官方存储库中打开了一个问题,并将在我了解更多需要解决的问题时更新此问题。

我正在添加此答案(并将随着我的进展进行更新),以防其他人仍在研究此问题

以前的用户似乎先下载文件,然后再处理它。这是不必要的,因为Papa解析应该能够处理读取流,并且应该可以通过管道“http”到达该流

下面是一个例子,有人在讨论我正在尝试做的事情,然后返回到下载文件,然后对其进行解析:

注意:在上面讨论的Baby解析中,现在Papa解析与节点Baby Parse一起工作已经被贬低了

下载文件解决方法 虽然下载并用papaparse解析并不能回答我的问题,但这是我目前唯一的解决方法,其他人可能会想使用这种方法

我要下载然后解析的代码当前看起来如下所示:

// Papa Parse for parsing CSV Files
var Papa = require('papaparse');
// HTTP and FS to enable Papa parse to download remote CSVs via node streams.
var http = require('http');
var fs = require('fs');

var destinationFile = "yourdestination.csv";

var download = function(url, dest, cb) {
  var file = fs.createWriteStream(dest);
  var request = http.get(url, function(response) {
    response.pipe(file);
    file.on('finish', function() {
      file.close(cb);  // close() is async, call cb after close completes.
    });
  }).on('error', function(err) { // Handle errors
    fs.unlink(dest); // Delete the file async. (But we don't check the result)
    if (cb) cb(err.message);
  });
};

download(feedURL, destinationFile, parseMe);

var parseMe = Papa.parse(destinationFile, {
  header: true,
  dynamicTyping: true,
  step: function(row) {
    console.log("Row:", row.data);
  },
  complete: function() {
    console.log("All done!");
  }
});

好的,我想我有一个答案。但我想只有时间能证明一切请注意,我的文件是带有制表符分隔符的.txt。

var fs = require('fs');
var Papa = require('papaparse');
var file = './rawData/myfile.txt';
// When the file is a local file when need to convert to a file Obj.
//  This step may not be necissary when uploading via UI
var content = fs.readFileSync(file, "utf8");

var rows;
Papa.parse(content, {
    header: false,
    delimiter: "\t",
    complete: function(results) {
        //console.log("Finished:", results.data);
    rows = results.data;
    }
});
实际上,您可以直接从http流使用解析CSV,这是我的主要示例之一。它还用于解析CSV

您在上面写的所有内容,以及中间的任何转换,都可以在几行代码中完成:

const {StringStream} = require("scramjet");
const request = require("request");

request.get("https://srv.example.com/main.csv")   // fetch csv
    .pipe(new StringStream())                       // pass to stream
    .CSVParse()                                   // parse into objects
    .consume(object => console.log("Row:", object))  // do whatever you like with the objects
    .then(() => console.log("all done"))
在您自己的示例中,您正在将文件保存到磁盘,即使使用PapaParse也不需要这样做。

Http(s)实际上在回调中有一个可读的流作为参数,因此这里有一个简单的解决方案

 try {
    var streamHttp = await new Promise((resolve, reject) =>
       https.get("https://example.com/yourcsv.csv", (res) => {
          resolve(res);
       })
    );
 } catch (e) {
    console.log(e);
 }

 Papa.parse(streamHttp, config);

经过大量的修改,我最终得到了一个使用异步流的工作示例,并且没有额外的库。它适用于远程和本地文件

我需要创建一个数据流和PapaParse流(使用
papa.NODE\u stream\u INPUT
作为
papa.parse()
的第一个参数),然后将数据导入PapaParse流。需要为PapaParse流上的
数据
完成
事件实现事件侦听器。然后,您可以将处理程序中解析的数据用于
finish
事件

请参见下面的示例:

const papa = require("papaparse");
const request = require("request");

const options = {/* options */};

const dataStream = request.get("https://example.com/myfile.csv");
const parseStream = papa.parse(papa.NODE_STREAM_INPUT, options);

dataStream.pipe(parseStream);

let data = [];
parseStream.on("data", chunk => {
    data.push(chunk);
});

parseStream.on("finish", () => {
    console.log(data);
    console.log(data.length);
});

parseStream的
data
事件恰好在CSV中的每一行运行一次(尽管我不确定这种行为是否得到保证)。希望这对别人有帮助

要使用本地文件而不是远程文件,您可以执行相同的操作,只需使用
fs
创建
数据流

const dataStream = fs.createReadStream("./myfile.csv");

(您可能希望使用
path.join
\uu dirname
来指定相对于文件所在位置而不是相对于文件运行位置的路径)

很高兴听到这个消息。:)。管道(新StringStream)当我使用此选项时,我将看到以下错误:[ts]无法将“new”与类型缺少调用或构造签名的表达式一起使用。请在后面添加括号:
new StringStream()
。.csvParse()在哪里方法来自?@SamSverko现在我注意到了-确实是
CSVParse
-我会在上面纠正这个问题。David如果这个方法有效(没有尝试过),那应该是接受答案!干得好!这应该是公认的答案,因为它实际上用papa parse回答了远程和本地文件的问题。最佳答案祝贺您发布了第一个答案!最好提供一些背景或指导,说明你的答案为什么适合这个问题。
const Papa = require("papaparse");
const { StringStream } = require("scramjet");
const request = require("request");

const req = request
  .get("https://example.com/yourcsv.csv")
  .pipe(new StringStream());

Papa.parse(req, {
  header: true,
  complete: (result) => {
    console.log(result);
  },
});