在 Node.js 中将 CSV 数据转换为 JSON
不久前,我编写了一项服务,该服务从 Yahoo! Finance 获取历史数据,以便根据证券的表现生成蒙特卡罗模拟。对于那些可能不熟悉蒙特卡罗模拟的人来说,这是一种概率建模技术,用于评估涉及随机变量的复杂场景中的潜在结果。通过模拟多个概率场景,蒙特卡罗模拟有助于分析投资、商业、物理和工程等各个领域的风险和不确定性。
Yahoo! Finance 的一大优点是它允许您以 CSV 格式下载历史数据。唯一的问题是我的服务(与许多服务一样)以 JSON 格式提供响应。这需要对传入数据进行转换。本文将详细介绍我如何使用出色的 Node.js csvtojson 库在 Node.js 中实现这一点。
比较 CSV 和 JSON 格式
让我们快速浏览一下这两种格式,并确定从一种格式转换为另一种格式需要做什么。
CSV(逗号分隔值)是一种用于存储表格数据的简单文件格式。在 CSV 文件中,每一行代表一行数据,每行中的值用逗号分隔。它是将数据导入数据库的最流行格式之一。例如,以下是 Yahoo! Finance 响应的示例:
Date,Open,High,Low,Close,Adj Close,Volume 2004-08-19,2.490664,2.591785,2.390042,2.499133,2.499133,897427216 2004-08-20,2.515820,2.716817,2.503118,2.697639,2.697639,458857488 2004-08-23,2.758411,2.826406,2.716070,2.724787,2.724787,366857939 2004-08-24,2.770615,2.779581,2.579581,2.611960,2.611960,306396159 2004-08-25,2.614201,2.689918,2.587302,2.640104,2.640104,184645512 2004-08-26,2.613952,2.688672,2.606729,2.687676,2.687676,142572401 2004-08-27,2.692408,2.705360,2.632383,2.643840,2.643840,124826132
同时,JSON(JavaScript 对象表示法)是一种轻量级的基于文本的数据交换格式,人类可以轻松读取和编写,机器也可以轻松解析和生成。它由两个主要结构组成:对象(用花括号 {} 括起来的键值对)和数组(用方括号 [] 括起来的有序列表)。为了让您了解它是什么样子,以下是我的 API 服务的部分响应:
{ "stockData": [ { "Date": "2019-01-02T00:00:00.000Z", "Close": 52.233059 }, { "Date": "2019-01-03T00:00:00.000Z", "Close": 50.745255 }, { "Date": "2019-01-04T00:00:00.000Z", "Close": 53.474648 }, { "Date": "2019-01-07T00:00:00.000Z", "Close": 53.35878 }, { "Date": "2019-01-08T00:00:00.000Z", "Close": 53.752831 }, // etc... ] }
csvtojson 入门
有几个类似的库,其中 csvtojson 是最活跃的库之一。要使用 Node 包管理器 (npm) 安装它,请在终端中运行以下命令:
npm i csvtojson
接下来,将以下导入语句添加到 Node 脚本的顶部:
const csvtojson = require("csvtojson");
就这样,我们就可以使用该库了!
转换数据
为了转换数据,我们需要做的就是使用几个选项调用 csvtojson 构造函数,然后将其链接到 fromString() 方法:
try { const response = await fetch(url); if (response.status !== 200) { throw new Error('Fetch failed. Received a response of ' + response.status); } const data = await csvtojson({ checkType: true, colParser: { "Date": dt => new Date(dt), "Open": "omit", "High": "omit", "Low": "omit", "Volume": "omit" } }).fromString(await response.text()); return data; } catch (err) { // handle errors }
还有一个 fromStream() 方法,但我发现通过分离调用可以更容易地处理与 fetch 相关的错误。
关于选项的一些信息:
我们可以使用点访问器符号来访问我们转换后的数据,即 `data.Date` 或 `data['Adj Close']`。
更改属性名称
API 响应对象中的“Close”属性实际上是“Adj Close”,但我不想这么叫,所以我改了属性名。为了转换发送给下游的结果,我们可以对每个 json 对象(即每个转换后的行)使用 .subscribe() 方法。
为此,我将“Adj Close”值分配给新属性,然后删除现有列。由于转换过程的异步性质,这一切都在 Promise 中完成:
const data = await csvtojson({ checkType:true, colParser: { "Date": dt => new Date(dt), "Open": "omit", "High": "omit", "Low": "omit", "Volume": "omit" } }).fromString(await response.text()).subscribe(jsonObj => new Promise(resolve => { // use the adj close jsonObj.Close = jsonObj['Adj Close']; delete jsonObj['Adj Close']; resolve(); }) );
结论
在本教程中,我们学习了如何转换 Yahoo! 财经的证券历史价格信息,使用 Node.js csvtojson 库从 CVS 转换为 JSON。
您可以在 RapidAPI 上试用 Monte Carlo 模拟器 API。我还编写了一个 API,用于获取股票买入价以获得期望的回报和一个信用卡总利息计算器。所有这些都可以免费使用,直到达到一定门槛,然后需要付费订阅。
如果您对我的 API 有任何疑问,或者想要咨询有关构建自定义 API 的信息,请随时给我发送电子邮件:raylsstr(AT)gmail(DOT)com。