web-dev-qa-db-ja.com

Nodejs / Papa Parseを使用してリモートCSVファイルを解析しますか?

私は現在、Nodeアプリからのリモートcsv製品フィードの解析に取り組んでおり、これを行うためにPapa Parseを使用したいと思っています(これまでブラウザで成功していました)。

Papa Parse Github: https://github.com/mholt/PapaParse

私の最初の試みとウェブ検索は、これがどのように行われるかを正確に明らかにしていません。 Papa Readmeによると、Papa ParseはNodeと互換性があるため、Node解析機能の一部を提供するために使用されていました)が廃止されました。

これは、将来この問題に遭遇した人のためのドキュメントのNodeセクションへのリンクです: https://github.com/mholt/PapaParse#papa-parse-for -node

そのドキュメントの段落から、NodeのPapa Parseはファイルの代わりに読み取り可能なストリームを解析できます。私の質問は;

NodeブラウザーのPapaがXMLHttpRequestを使用して同じ目標を達成する方法と同様の方法で、Papaを使用してリモートCSVをダウンロード/解析するために読み取り可能なストリーム機能を利用する方法はありますか?

将来の可視性についてここで説明されているリモートファイル解析機能を利用しようとするトピックを検索する場合(および同様の質問が繰り返されないようにする場合) http://papaparse.com/docs#remote-files とすると、コンソールで次のエラーが発生します。

"未処理の拒否ReferenceError:XMLHttpRequest is not defined"

公式リポジトリで問題を公開しました。解決する必要のある問題について詳しく知り次第、この質問を更新します。

8
Necevil

実際には scramjetと呼ばれる軽量のストリーム変換ライブラリ を使用できます。httpストリームから直接CSVを解析することが私の主な例の1つです。また、CSVを解析するために PapaParse を使用します。

上記のすべての変換は、間に変換があれば、数行で実行できます。

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でも不要です。

5

OK、それで私はこれに対する答えがあると思います。しかし、時間だけが教えてくれると思います。 私のファイルはタブ区切りの.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;
    }
});
7
TheDuke

たくさんのいじくりの後で、私はついにストリームを使用してこれの実際の例を得ました。以下の例をご覧ください。

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の「データ」イベントは、CSVの行ごとに1回実行されます。これが誰かを助けることを願っています!

また:リモートファイルの代わりにローカルファイルを使用するには、同じことを実行できますが、

fs.createReadStream("./myfile.csv").pipe(parseStream);

リクエストの代わりに。

1
David Liao

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);
1
ThomasP1988

他の誰かがまだこの問題を調査している場合に備えて、私はこの回答を追加します(そして、進捗状況に応じて更新します)。

以前のユーザーが最初にファイルをダウンロードしてから処理したようです。 Papa Parseは読み取りストリームを処理できる必要があり、「http」GETをそのストリームにパイプすることができるはずなので、これは必要ではありません(SHOULD NOT)。

これは、誰かが私が何をしようとしているのかを話し合い、ファイルをダウンロードして解析する例です: https://forums.meteor.com/t/processing-large-csvs-in-meteor -js-with-papaparse/32705/4

注:上記のベビーパースについて説明しましたが、パパパースはNodeベビーパースは廃止されました。

ファイルのダウンロードの回避策

ダウンロードしてからPapa Parseで解析することは私の質問に対する回答ではありませんが、これが現時点で私が持っている唯一の回避策であり、他の誰かがこの方法論を使用したいと思うかもしれません。

ダウンロードして解析する私のコードは現在次のようになります:

// 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!");
  }
});
1
Necevil