Как разделить эти словари в этом выпуске json?

#python #json #dictionary

Вопрос:

Я попытался сделать код «с открытым .json», в который была записана информация о нескольких продуктах. Однако в .файл json, каждый словарь не отделен друг от друга запятой. Это нормально или я что-то неправильно закодировал?

 for product in data['prods']:
    product_name = product['name']
    prod_id = product['Id']
    prod_price = product['price']
    link = 'https://24h.pchome.com.tw/prod/'   prod_id
    today = str(datetime.date.today())
    fileName = today   '_'   keyword   '_Pchome.json'
    try:
        with open(fileName, 'a', encoding='utf-8') as f:
             json.dump({
                      "名稱":product_name,
                      "價格":prod_price,
                      "網址":link, 
             }, f, ensure_ascii=False, indent=4, skipkeys=True)
    except Exception as err:
        print(str(err))
 

Отредактировано: Изменил свой код на что-то вроде этого(с дополнительной информацией, так как люди задаются вопросом).

 keyword = str(input('找什麼? '))
pages = 10
parse_word = urllib.parse.quote(keyword)
for page in list(range(1, pages)):
    response = requests.get('https://ecshweb.pchome.com.tw/search/v3.3/all/results?q='   parse_word   'amp;page='   str(page)   'amp;sort=rnk/dc')
    raw_data = response.content.decode('utf-8')
    data = json.loads(raw_data)
    try:
        myData = []
        for product in data['prods']:
            product_name = product['name']
            prod_id = product['Id']
            prod_price = product['price']
            link = 'https://24h.pchome.com.tw/prod/'   prod_id
            myData.append({
                "名稱":product_name,
                "價格":prod_price,
                "網址":link
            })
            today = str(datetime.date.today())
            fileName = today   '_'   keyword   '_Pchome.json'
            try:
                with open(fileName, 'a', encoding='utf-8') as f:
                    json.dump(myData, f, ensure_ascii=False, indent=4, skipkeys=True)
            except Exception as err:
               print(str(err))
    except Exception as err:
        print(str(err))
print('完成!') 
 

и мои результаты становятся чем-то ниже..на этот раз с двойной квадратной скобкой, хотя…я сделал что-то не так

 [
    {
        "名稱": "ASUS VivoBook Flip TP470EA-0112K1135G7 黑(i5-1135G7/8G/512G PCIe/Touch/Glare/W10/FHD/14)",
        "價格": 27900,
        "網址": "https://24h.pchome.com.tw/prod/DHAFLY-A900BKJJV"
    }
][
    {
        "名稱": "ASUS VivoBook Flip TP470EA-0112K1135G7 黑(i5-1135G7/8G/512G PCIe/Touch/Glare/W10/FHD/14)",
        "價格": 27900,
        "網址": "https://24h.pchome.com.tw/prod/DHAFLY-A900BKJJV"
    },
    {
        "名稱": "ASUS X515JF-0281G1035G1 星空灰(i5-1035G1/8G/MX130-2G/512G PCIe/W10/FHD/15.6)",
        "價格": 23900,
        "網址": "https://24h.pchome.com.tw/prod/DHAFL9-A900BLVZR"
    }
][
    {
        "名稱": "ASUS VivoBook Flip TP470EA-0112K1135G7 黑(i5-1135G7/8G/512G PCIe/Touch/Glare/W10/FHD/14)",
        "價格": 27900,
        "網址": "https://24h.pchome.com.tw/prod/DHAFLY-A900BKJJV"
    },
    {
        "名稱": "ASUS X515JF-0281G1035G1 星空灰(i5-1035G1/8G/MX130-2G/512G PCIe/W10/FHD/15.6)",
        "價格": 23900,
        "網址": "https://24h.pchome.com.tw/prod/DHAFL9-A900BLVZR"
    },
    {
        "名稱": "ASUS X515MA-0471GN4120 星空灰(Celeron N4120/4G/256G PCIe/W10/FHD/15.6)",
        "價格": 14900,
        "網址": "https://24h.pchome.com.tw/prod/DHAFM4-A900BL8H7"
    }
 

Вот изображение образца из моего файла json.

Образец из файла JSON

Комментарии:

1. у меня есть образец твоего . файл json? Кроме того, json.dump(<dict>) будет выведена строка JSON, соответствующая содержимому вашего <dict> .

2. Я не понимаю вашего вопроса. Как выглядят ваши данные? Что ты пытаешься отделить?

3. отредактировал код, хотя это могло бы помочь

Ответ №1:

Ваш подход сам по себе не является неправильным, но, безусловно, нестандартным. Типичный шаблон состоит в том, чтобы объединить все, что вам нужно, в единую структуру данных, а затем json.dump(...) только один раз. Таким образом, вы не тратите ресурсы системного ввода-вывода, открывая файл снова и снова. Затем вы можете просто загрузить все продукты сразу с json.load(...) :

 product_data = []
for product in data["prods"]:
    product_name = product["name"]
    prod_id = product["Id"]
    prod_price = product["price"]
    link = "https://24h.pchome.com.tw/prod/"   prod_id
    product_data.append({"名稱": product_name, "價格": prod_price, "網址": link})
try:
    with open(fileName, "w", encoding="utf-8") as f:
        json.dump(product_data, f, ensure_ascii=False, indent=4, skipkeys=True)
except Exception as err:
    print(str(err))
 

Тем не менее, иногда существуют законные причины, по которым вы хотели бы обрабатывать различные товары (продукты в вашем случае) независимо, особенно если их сбор-это длительный процесс, и вы хотите добиться какой-то отказоустойчивости, если что-то пойдет не так в середине ИЛИ если продуктов так много, и вы не хотите загружать их все сразу. Однако проблема с вашим подходом заключается в том, что вы не будете знать, когда чтобы прекратить чтение файла, чтобы получить каждый отдельный объект json. Если вы хотите добиться чего-то подобного, просто пишите новую строку ( запятая, если хотите, чтобы она выглядела как один допустимый json) после каждой итерации или вместо этого посмотрите jsonlines

Комментарии:

1. была отредактированная версия в вопросе, но теперь с другой проблемой, я думаю 😛

2. да, та же проблема в вашей отредактированной версии вопроса, вы все равно захотите инициализировать только my_pages и добавлять к ним все данные myData, а затем снова просто сбросить один раз ИЛИ вручную написать запятую новую строку между каждой страницей (или использовать jsonlines)

Ответ №2:

Вы добавляете в файл строковую версию данных, из-за чего скобки располагаются рядом друг с другом без запятой. Это может привести к ошибке при попытке чтения из файла.

Вместо этого вам следует сделать так, чтобы ваш файл json начинался как список, импортировать файл json в свой код, добавить свои объекты, а затем переписать в файл.

Вы могли бы сделать следующее с помощью кода, аналогичного этому:

 myData = json.load(open(fileName))

for product in data['prods']:
  product_name = product['name']
  prod_id = product['Id']
  prod_price = product['price']
  link = 'https://24h.pchome.com.tw/prod/'   prod_id
  today = str(datetime.date.today())
  fileName = today   '_'   keyword   '_Pchome.json'
  myData.append({
    "名稱": product_name,
    "價格": prod_price,
    "網址": link,
  })

try:
  with open(fileName, 'w', encoding='utf-8') as f:
    json.dump(myData, f, ensure_ascii=False, indent=4, shipkeys=True)
except Exception as err:
  print(str(err))
 

В качестве временного решения, если вы хотите исправить файл json, вы можете поместить квадратные скобки в начале и в конце файла (при условии, что их нет), чтобы превратить его в массив. Кроме того, вы также можете добавлять запятые между каждым объектом в массиве.

Комментарии:

1. была отредактированная версия в вопросе, но теперь с другой проблемой, я думаю 😛

2. @user15301225 Двойные скобки возникают из-за with open(fileName, 'a', encoding='utf-8') as f: . Это a означает, что он просто добавится в файл, вместо того, чтобы переписывать. В нашем случае мы хотим переписать его, так как у нас уже есть полный файл JSON, загруженный в Python. Поэтому вы можете просто заменить эту строку на with open(fileName, 'w', encoding='utf-8') as f:

3. нет проблем! Если это решение исправило вашу проблему, вы можете пометить ее как решенную