将JSON文件加载到字典中,而不是字符串或列表中

时间:2018-10-21 20:26:14

标签: python json parsing dictionary web-scraping

我使用以下简化代码在线抓取数据后创建了一个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文件的外观,但是我无法使用{{ 1}}或json1_file["asin"],因为读取的文件是字符串而不是字典。

json1_file["reviews"]

使用TypeError: string indices must be integers 函数,我仍然可以打印正确的内容,但是我还无法弄清楚如何从JSON文件访问类似字典的对象来遍历键和值。

以下代码可打印文件的内容,但是当我尝试遍历键和值时会引发错误(json.load()):

AttributeError: '_io.TextIOWrapper' object has no attribute 'items'

上面的代码有什么问题,应该进行哪些调整才能将文件加载到字典中?

1 个答案:

答案 0 :(得分:0)

  

字符串索引必须为整数

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

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 

或为每个刮擦编写一个唯一的文件,然后必须循环读取所有文件。

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