私は現在、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"
公式リポジトリで問題を公開しました。解決する必要のある問題について詳しく知り次第、この質問を更新します。
実際には 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でも不要です。
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;
}
});
たくさんのいじくりの後で、私はついにストリームを使用してこれの実際の例を得ました。以下の例をご覧ください。
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);
リクエストの代わりに。
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);
他の誰かがまだこの問題を調査している場合に備えて、私はこの回答を追加します(そして、進捗状況に応じて更新します)。
以前のユーザーが最初にファイルをダウンロードしてから処理したようです。 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!");
}
});