如何解析换行符分隔的 JSON

时间:2021-05-10 07:52:34

标签: javascript json google-apps-script

我正在使用应用脚本从 GCS 存储桶中提取 JSON 文件。数据存储为以 JSON 分隔的换行符。它作为一个大对象到达,这使得无法以编程方式访问内部数据。

我的目标是用 merchant_id 分隔每个元素。我尝试使用 \n 作为参数拆分数据。但是我很难将对象转换为字符串并再次返回。 对响应调用 JSON.parse 会给我错误 Unexpected token { in JSON at position 1766。虽然这确实将 JSON 中的每个元素分开,但对每个元素单独调用 JSON.parse 会给我一个 Unexpected end of JSON input 错误。

功能

function myFunction() {

let url = 'url_address';
let storedData = [];
let response = UrlFetchApp.fetch(url, {'muteHttpExceptions': true});
let str = response.toString();
let storedResponse = str.split("\n");

storedResponse.forEach((data) => {
   storedData.push(JSON.parse(data));
});
}

forEach 中的 data 示例

{"product_data_timestamp":"2021-05-06 UTC","product_id":"product_id_here","merchant_id":"merchant_id_here","aggregator_id":"agg_id_here","offer_id":"offer_id_here","title":"furniture","description":"description","link":"link","additional_image_links":[],"content_language":"en","target_country":"GB","channel":"online","google_expiration_date":"2021-05-31 22:00:27.517 UTC","availability":"in stock","brand":"brand","color":"black","condition":"new","custom_labels":{"label_0":"GBP"},"item_group_id":"id","mpn":"mpn_id","price":{"value":"129.99","currency":"GBP"},"google_product_category_ids":[],"product_type":"headboards","additional_product_types":[],"destinations":[{"name":"Shopping","status":"approved"}],"issues":[]}

2 个答案:

答案 0 :(得分:1)

add-migration 会给你一个 HTTPResponse 对象而不是一个 JSON 字符串。您需要像这样获得响应的内容

UrlFetchApp.fetch()

答案 1 :(得分:1)

正如 doubleunary 所说,您可能错过了 .getContentText()

总结:response 来自:

let response = UrlFetchApp.fetch(url, {'muteHttpExceptions': true});

是一个 HTTPResponseObject,因此尝试将其解析为字符串或 JSON 是行不通的。要修复它,您需要添加对 getContentText() 的调用。

除非 doubleunary 的答案不起作用,因为结果是 BigQuery 换行符分隔的 JSON,所以您仍然需要按照您的建议用换行符拆分它。

所以只需添加该步骤:

function myFunction() {

let url = 'url_address';
let storedData = [];
let response = UrlFetchApp.fetch(url, {'muteHttpExceptions': true});
let contentText = response.getContentText();
let storedResponse = contentText.split("\n");

storedResponse.forEach((data) => {
   storedData.push(JSON.parse(data));
});
}

应该可以解决您的问题,请尝试一下(因为我无法测试)。

参考

编辑:

由于在 JSON 中 中存在换行符,您可能会得到一些无效的 JSON 行。

减少这种情况的一种方法是用右花括号和换行符分开 "}\n"。尽管理论上,JSON 行也可以包含此内容。

function myFunction() {

let url = 'url_address';
let storedData = [];
let response = UrlFetchApp.fetch(url, {'muteHttpExceptions': true});
let contentText = response.getContentText();
let storedResponse = contentText.split("}\n");

storedResponse.forEach((data) => {
   storedData.push(JSON.parse(data + "}")); // you would need to add the ending brace again to parse it
});
}

如果 JSON 结构始终相同,您可以采用的另一种方法是使用这样的正则表达式:

^{.+"issues":\[.+\]}$/gm

查找以换行符开头的文本块,{ 之间的内容数量可变,然后 "issues":[ 与另一个关于数据的变量,最后 ]}\n .这应该会捕获 JSON 中可能导致格式错误的 JSON 从 split 中出现的大多数可能换行符的实例。 gm 是允许多个结果的全局标志,m 是多行标志,允许您识别以 ^$ 字符开始和结束的行。

您可以使用 string.match 实现它:

function myFunction() {

let url = 'url_address';
let storedData = [];
let response = UrlFetchApp.fetch(url, {'muteHttpExceptions': true});
let contentText = response.getContentText();
let storedResponse = contentText.match(/^{.+"issues":\[\]}$/gm);

storedResponse.forEach((data) => {
   storedData.push(JSON.parse(data));
});
}
相关问题