#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.
Комментарии:
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. нет проблем! Если это решение исправило вашу проблему, вы можете пометить ее как решенную