首页 > 解决方案 > 读取存储在一行中的字典文本文件

问题描述

问题

我有一个文本文件,其中记录了SemanticScholar API请求的研究论文的元数据。但是,当我编写请求的数据时,我忘记"\n"为每个单独的记录添加。这导致看起来像

{<metadata1>}{<metadata2>}{<metadata3>}...

如果我确实添加了"\n".

{<metadata1>}
{<metadata2>}
{<metadata3>}
...

现在,我想读取数据。由于所有元数据现在都存储在一行中,我需要做一些黑客攻击

import json
with open("metadata.json", "r") as f:
    for line in f.readline().split("{"):
        print(json.loads("{" + line.replace("\'", "\"")))

但是,仍然有错误消息

JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

我想知道我应该怎么做才能恢复我收集的所有元数据?

MWE

请注意,为了获取metadata.json我使用的文件,请使用以下代码,它应该可以开箱即用。

import json
import urllib
import requests

baseURL = "https://api.semanticscholar.org/v1/paper/"
paperIDList = ["200794f9b353c1fe3b45c6b57e8ad954944b1e69",
               "b407a81019650fe8b0acf7e4f8f18451f9c803d5",
               "ff118a6a74d1e522f147a9aaf0df5877fd66e377"]

for paperID in paperIDList:
    response = requests.get(urllib.parse.urljoin(baseURL, paperID))
    metadata = response.json()
    record = dict()
    record["title"] = metadata["title"]
    record["abstract"] = metadata["abstract"]
    record["paperId"] = metadata["paperId"]
    record["year"] = metadata["year"]
    record["citations"] = [item["paperId"] for item in metadata["citations"] if item["paperId"]]
    record["references"] = [item["paperId"] for item in metadata["references"] if item["paperId"]]
    with open("metadata.json", "a") as fileObject:
        fileObject.write(json.dumps(record))

标签: python

解决方案


问题是,当你这样做时,split("{")你得到的第一个项目是空的,对应于 opening {。只需忽略第一个元素,一切正常(我r在引号替换中添加了一个,因此 python 将其视为字符串文字并正确替换它们):

with open("metadata.json", "r") as f:
     for line in f.readline().split("{")[1:]:
         print(json.loads("{" + line).replace(r"\'", r"\""))

正如评论中所建议的,我实际上建议重新创建文件或保存替换为的新}{版本}\n{

with open("metadata.json", "r") as f:
    data = f.read()
data_lines = data.replace("}{","}\n{")
with open("metadata_mod.json", "w") as f:
    f.write(data_lines)

这样,您将根据需要获得每行论文的元数据。


推荐阅读