修复 Node Js 中的 Facebook JSON 编码

Fixing Facebook JSON Encoding in Node Js

我正在尝试解码您下载数据时从 Facebook 获得的 JSON。我正在使用节点 JS。数据有很多奇怪的 unicode 转义符,实际上没有意义。示例:

"messages": [
    {
      "sender_name": "Emily Chadwick",
      "timestamp_ms": 1480314292125,
      "content": "So sorry that was in my pocket \u00f0\u009f\u0098\u0082\u00f0\u009f\u0098\u0082\u00f0\u009f\u0098\u0082",
      "type": "Generic"
    }
]

应该解码为 So sorry that was in my pocket 。使用 fs.readFileSync(filename, "utf8") 得到我 So sorry that was in my pocket ððð,这是 mojibake。

提到它搞砸了 latin1 编码,您可以编码为 latin1,然后解码为 utf8。我试着这样做:

import iconv from 'iconv-lite';
function readFileSync_fixed(filename) {
    var content = fs.readFileSync(filename, "binary");
    return iconv.decode(iconv.encode(content, "latin1"), "utf-8")
}
console.log(JSON.parse(readFileSync_fixed(filename)))

但我还是得到了 mojibake 版本。谁能指出我正确的方向?我不熟悉 iconv 在这方面的工作方式。

以某种方式解决了...。如果有更好的方法,请告诉我。

所以,这是修改后的函数

readFacebookJson(filename) {
    var content = fs.readFileSync(filename, "utf8");
    const json = JSON.parse(converted)
    return json
}

fixEncoding(string) {
    return iconv.decode(iconv.encode(string, "latin1"), "utf8")
}

不是 readFileSync() 搞砸了,是 JSON.parse()。所以 - 我们像往常一样将文件读取为 utf8,但是,然后我们需要对现在是 JSON 文件属性的字符串执行 latin1 encoding/decoding,而不是整个 JSON 文件在它被解析之前。我用 map().

做了这个
messages = readFacebookJson(filename).messages.map(message => {
    const toReturn = message;
    toReturn.sender_name = fixEncoding(toReturn.sender_name)
    if (typeof message.content !== "undefined") {
        toReturn.content = fixEncoding(message.content)
    }
    return toReturn;
}),

这里的问题当然是某些属性可能会丢失。因此,请确保您知道哪些属性包含哪些内容。

为此有非常简单的解决方案

拳头安装utf8

npm i utf8.

您的代码将如下所示

const fs = require('fs');
const utf8 = require('utf8');
let rawdata = fs.readFileSync('JSON_FILE_NAME');
let data = JSON.parse(rawdata);

for (let i = 0;i < data["messages"].length;i++) {
    if (data["messages"][i]["content"] != undefined) {
        console.log(utf8.decode(data["messages"][i]["content"]))
    }
}