【问题标题】:Load JSON file into a dictionary and not string or list将 JSON 文件加载到字典中,而不是字符串或列表
【发布时间】:2019-03-25 22:48:48
【问题描述】:

我使用以下简化代码在线抓取数据后创建了一个 JSON 文件:

for item in range(items_to_scrape)
    az_text = []
    for n in range(first_web_page, last_web_page):
            reviews_html = requests.get(page_link)
            tree = fromstring(reviews_html.text)
            page_link = base_url + str(n)
            review_text_tags = tree.xpath(xpath_1)
            for r_text in review_text_tags:
                review_text = r_text.text
                az_text.append(review_text)
    az_reviews = {}
    az_reviews[item] = az_text
    with open('data.json', 'w') as outfile:
        json.dump(az_reviews , outfile)

可能有更好的方法来创建一个 JSON 文件,其中第一个键等于项目编号,第二个键等于该项目的评论列表,但是我目前卡在打开 JSON 文件以查看项目已被抓取。

JSON 文件的结构如下所示:

{
  "asin": "0439785960",
  "reviews": [
    "Don’t miss this one!",
    "Came in great condition, one of my favorites in the HP series!",
    "Don’t know how these books are so good and I’ve never read them until now. Whether you’ve watched the movies or not, read these books"
  ]
}

似乎更接近解决方案的不成功尝试如下:

import json
from pprint import pprint

json_data = open('data.json', 'r').read()
json1_file = json.loads(json_data)
print(type(json1_file))
print(json1_file["asin"])

它返回一个字符串,该字符串完全复制了我在抓取过程中使用的 print() 函数的结果,以检查 JSON 文件的外观,但我无法使用 @987654326 访问 asins 或评论@ 或 json1_file["reviews"] 因为读取的文件是字符串而不是字典。

TypeError: string indices must be integers

使用json.load() 函数,我仍然可以打印正确的内容,但我无法弄清楚如何从 JSON 文件访问类字典对象以遍历键和值。

以下代码打印文件的内容,但在我尝试遍历键和值时引发错误 (AttributeError: '_io.TextIOWrapper' object has no attribute 'items'):

with open('data.json', 'r') as content:
    print(json.load(content))
    for key, value in content.items():
        print(key, value)

上面的代码有什么问题,应该调整什么以将文件加载到字典中?

【问题讨论】:

  • “我已经尝试了很多方法”没有帮助。如果你不展示你的尝试,没有人能说出你犯了什么样的错误。
  • 我已经用错误的尝试更新了问题,你能发现我犯了哪些错误吗?谢谢
  • 你认为你所有的尝试都应该奏效吗?你认为有人应该分析他们每个人。选择一个你认为应该起作用的,然后试着找出它为什么不起作用。去谷歌上查询。然后问一个具体的问题,例如我希望这个函数做一件事(例如,因为规范是这样说的),但它做了另一件事。显示发生了什么错误。然后你会有一个有效的问题。另见how to askhow to create a minimal, complete and verifiable example
  • 如果你有文件,你真的应该使用json.load()

标签: python json parsing dictionary web-scraping


【解决方案1】:

字符串索引必须是整数

您将数据写成字符串,而不是字典。删除转储,仅转储

with open('data.json', 'w') as outfile:
    json.dump(az_reviews, outfile, indent=2, ensure_ascii=False) 

将文件加载到字典中需要调整什么?

一旦你解析一个 JSON 对象,而不是一个字符串,那么除了可能不使用读取之外什么都没有,然后加载,而只是 json.load


另一个问题似乎是您在每次循环迭代时都覆盖了文件

相反,您可能希望打开一个文件,然后循环并写入该文件

data = {} 
for item in range(items_to_scrape):
    pass # add to data
# put all data in one file 
with open('data.json', 'w') as f:
    json.dump(data, f)

在这种情况下,我建议您将 asin 存储为键,将评论存储为值

asin = "123456"  # some scraped value 
data[asin] = reviews 

或者为每个scrape写一个唯一的文件,然后你必须循环读取它们。

for item in range(items_to_scrape):
    data = {} 
    # add to data
    with open('data{}.json'.format(item), 'w') as f: 
        json.dump(data, f)

【讨论】:

  • 感谢 cricket_007 分享您的知识,我可能会重新调整抓取代码以仅包含 asin 编号和评论文本,这将使输出的 JSON 文件更轻更合适。但是,我需要弄清楚如何从 JSON 文件中访问键和值,因为抓取代码的要求之一是访问和考虑已经抓取并在文件内部的 asins,并且只抓取我列表中剩余的那些。
  • 您可以像访问任何其他字典一样从解析的 JSON 文件中访问数据
  • 当我尝试在 json.load() 函数之后迭代键和值时,出现“AttributeError: '_io.TextIOWrapper' 对象没有属性 'items'”错误。我将该部分包含在已编辑问题的底部,您认为该部分代码有什么问题?
  • 尝试的代码如下:以 open('data.json', 'r') 作为内容: print(json.load(content)) 为 key,content.items() 中的值:打印(键,值)
  • 我已经编辑了抓取代码以将 asin 转储为键并将评论转储为值,还修复了删除转储并仅留下转储来写入 JSON 文件的错误。还有什么其他错误问题?
猜你喜欢
  • 2014-10-26
  • 2013-08-07
  • 2019-09-17
  • 1970-01-01
  • 2021-09-26
  • 1970-01-01
  • 1970-01-01
  • 2017-06-21
相关资源
最近更新 更多