Допустимая загрузка JSON в файле Python

Возникла проблема с моим JSON:

Первой проблемой был SyntaxError: Non-ASCII character '\xe2' in file, поэтому я добавил # -*- coding: utf-8 -*- в начало файла.

Затем проблема превратилась в проблему, когда я загружаю свой JSON x = json.loads(x): ValueError: Expecting , delimiter: line 3 column 52 (char 57). Я сослался на это решение stackoverflow и поэтому добавил r перед моим JSON:

x = r"""[
  { my validated json... }
]"""

Но тут появляется ошибка TypeError: sequence item 3: expected string or Unicode, NoneType found - Думаю, что r как-то скидывает?

JSON Похож на следующее:

[
  {
    "brief": "Brief 1",
    "description": "Description 1",
    "photos": [
      "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example.jpg?0101010101010",
      "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example2.jpg?0101010101010",
      "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example3.jpg?0101010101010"
    ],
    "price": "145",
    "tags": [
      "tag1",
      "tag2",
      "tag3"
    ],
    "title": "Title 1"
  },
  {
    "brief": "Brief 2",
    "description": "Description 2",
    "photos": [
      "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example4.jpg?0101010101010",
      "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example5.jpg?0101010101010"
    ],
    "price": "150",
    "tags": [
      "tag4",
      "tag5",
      "tag6",
      "tag7",
      "tag8"
    ],
    "title": "Title 2"
  },{
    "brief": "blah blah 5'0\" to 5'4\"",
    "buyerPickup": true,
    "condition": "Good",
    "coverShipping": false,    
    "description": "blah blah 5'0\" to 5'4\". blah blah.Size L/20”\n 5’8-5’11\n29lbs\n3x7 speed\n\n  \r\n\r\n",
    "photos": [
      "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-010101.jpeg?11111",
      "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-020202?111111"
    ],
    "price": "240",
    "tags": [
      "tag2",
      "5'0\"-5'4\""
    ],
    "title": "blah blah 17\" Frame",
    "front": "https://firebasestorage.googleapis.com/v0/b/example.appspot.com/o/Images%2F0007891113.jpg?alt=media&token=111-11-11-11-111"    
  } 
]

ТЕКУЩИЙ КОД

# -*- coding: utf-8 -*-

import csv
import json

x = """[
      {
        "brief": "Brief 1",
        "description": "Description 1",
        "photos": [
          "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example.jpg?0101010101010",
          "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example2.jpg?0101010101010",
          "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example3.jpg?0101010101010"
        ],
        "price": "145",
        "tags": [
          "tag1",
          "tag2",
          "tag3"
        ],
        "title": "Title 1"
      },
      {
        "brief": "Brief 2",
        "description": "Description 2",
        "photos": [
          "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example4.jpg?0101010101010",
          "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example5.jpg?0101010101010"
        ],
        "price": "150",
        "tags": [
          "tag4",
          "tag5",
          "tag6",
          "tag7",
          "tag8"
        ],
        "title": "Title 2"
      },{
        "brief": "blah blah 5'0\" to 5'4\"",
        "buyerPickup": true,
        "condition": "Good",
        "coverShipping": false,    
        "description": "blah blah 5'0\" to 5'4\". blah blah.Size L/20”\n 5’8-5’11\n29lbs\n3x7 speed\n\n  \r\n\r\n",
        "photos": [
          "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-010101.jpeg?11111",
          "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-020202?111111"
        ],
        "price": "240",
        "tags": [
          "tag2",
          "5'0\"-5'4\""
        ],
        "title": "blah blah 17\" Frame",
        "front": "https://firebasestorage.googleapis.com/v0/b/example.appspot.com/o/Images%2F0007891113.jpg?alt=media&token=111-11-11-11-111"    
      } 
    ]"""

x = json.loads(x)

f = csv.writer(open("example.csv", "wb+"))

f.writerow(["Handle","Title","Body (HTML)", "Vendor","Type","Tags","Published","Option1 Name","Option1 Value","Variant Inventory Qty","Variant Inventory Policy","Variant Fulfillment Service","Variant Price","Variant Requires Shipping","Variant Taxable","Image Src"])

    for x in x:

        allTags = "\"" + ','.join(x["tags"]) + "\""
        images = x["photos"]
        f.writerow([x["title"],
                    x["title"],
                    x["description"],
                    "Vendor Name",
                    "Widget",
                    allTags,
                    "TRUE",
                    "Title",
                    "Default Title",
                    "1",
                    "deny",
                    "manual",
                    x["price"],
                    "TRUE",
                    "TRUE",
                    images.pop(0) if images else None])
        while images:
            f.writerow([x["title"],None,None,None,None,None,None,None,None,None,None,None,None,None,None,images.pop(0)])

СООБЩЕНИЕ ОБ ОШИБКЕ: Полное отслеживание, которое я вижу: Отслеживание (последний вызов последний):

Traceback (most recent call last): File "runnit2.py", line 976, in <module> allTags = "\"" + ','.join(x["tags"]) + "\"" TypeError: sequence item 3: expected string or Unicode, NoneType found

Обновлено: Я определил, что данные, а именно [x ["title"], x ["title"], x ["description"], содержат некоторые символы, которые не нравятся коду. 'ascii' codec can't encode character u'\u201d' in position 9: ordinal not in range(128). Я сделал быстрое исправление с помощью x ["description"]. Encode ('utf-8') и т. д., Но он почти полностью устраняет все, что находится в этой ячейке. Есть ли лучший способ не удалять все после оскорбительного персонажа?

Вы также можете добавить свой JSON? Ошибки предполагают, что проблема может быть там.

hgazibara 06.07.2018 20:57

В общем, нам нужен минимальный воспроизводимый пример, прежде чем мы сможем отладить вашу проблему. С тем, что вы нам дали, все, что можно увидеть, это то, что где-то в вашем коде или данных должно быть что-то не так, что вам не очень поможет.

abarnert 06.07.2018 21:01

@hgazibara Я включил близкий пример JSON, который, как мне кажется, представляет наиболее запутанные части JSON со странными символами и т. д.

maudulus 06.07.2018 21:23

Не могу воспроизвести. Для меня это нормально (python 3.6.2). Какую версию Python вы используете?

glibdud 06.07.2018 21:26

@glibdud Python 2.7.10

maudulus 06.07.2018 21:27

У меня тоже хорошо загружается в 2.7.13 (после добавления r перед строкой JSON).

glibdud 06.07.2018 21:29

Когда я запускаю код в том виде, в каком был опубликован, я получаю сообщение об ошибке в строке "blah blah 5'0, что имеет смысл, потому что \" в необработанном строковом литерале Python - это просто ", а не кавычка с обратной косой чертой. Когда я добавляю префикс r, как вы говорите, код работает, как в Python 3, так и в Python 2. Отправьте код, который действительно демонстрирует исключение, с которым вам нужна помощь.

abarnert 06.07.2018 22:13

Кроме того, опубликуйте полную трассировку, а не только описание исключения. Я не вижу ничего в опубликованном вами коде, который мог бы сгенерировать это исключение, но я могу ошибаться в этом, и если да, то показ исключения укажет нам, в чем я ошибаюсь.

abarnert 06.07.2018 22:13

Это сообщение об ошибке похоже на то, которое вы получите от str.join, если передадите ему последовательность вроде ['abc', 'def', 'ghi', None]. Итак, если бы мне пришлось сделать безумную догадку: даже если вы создаете csv.writer, вы также пытаетесь создать строки вручную с помощью ','.join(something). И этот something - это список, содержащий значения, которые вы построили на основе поисковых запросов, таких как x[i].get(key). И один из этих вызовов get вернул None, потому что в одном из ваших dicts такого ключа не было.

abarnert 06.07.2018 22:19

@abarnert Думаю, вы правы - я опубликовал полный пример - как вы думаете, может ли это быть проблемой?

maudulus 06.07.2018 22:27

Я запускаю точный код, который я опубликовал, и у меня проблема с Python 2.7.10. Я добавляю полную обратную связь к своему сообщению

maudulus 06.07.2018 22:33

Вы только что опубликовали трассировку, которую вы уже исправили, добавив префикс r к строковому литералу JSON. Если это ваша единственная проблема, то ваш вопрос - просто дубликат ответа, который вы уже нашли и на который ссылались в своем вопросе. Если вам нужна помощь с проблемой Другие, той, которая у вас все еще есть, отредактируйте свой вопрос так, чтобы он касался этой проблемы: включите r в свой код и предоставьте нам трассировку другого исключения.

abarnert 06.07.2018 22:36

Кроме того, вы не можете запускать точный код, который вы опубликовали, потому что опубликованный вами код вызывает IndentationError еще до того, как что-либо будет выполнено.

abarnert 06.07.2018 22:39

@abarnert вы правы, извините за корректировку трассировки ..

maudulus 06.07.2018 22:49

Извините, я все еще не могу воспроизвести проблему. Опять же, код, который вы разместили здесь, не будет запущен, потому что в нем все еще есть проблема r, проблема с символом Unicode и ошибка отступа. Но если я все это исправлю, оно работает.

abarnert 06.07.2018 22:59

Я не могу опубликовать все свои данные в Интернете. Я пытался анонимизировать его, но это слишком много данных. Есть ли какой-нибудь инструмент, который вы используете для такого рода вещей? Я скопировал ваш точный пример и просто ввел свои данные, и я получаю сообщение об ошибке SyntaxError: Non-ASCII character '\xe2' in file runnit2.py on line 345, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details.

maudulus 06.07.2018 23:04

Я добавил # -*- coding: utf-8 -*- вверху и получил ошибку: Traceback (most recent call last):File "example.py", line 977, in <module>allTags = "\"" + ','.join(x["tags"]) + "\""TypeError: sequence item 3: expected string or Unicode, NoneType found

maudulus 06.07.2018 23:08

@maudulus Данные, которые вы разместили в ссылке на код-шеринг, определенно недействительны в формате JSON.

Salman A 08.07.2018 21:32

Я удалил измененный wb + на w + в python3, и это работало без ошибок.

Rohit Salunke 13.07.2018 20:35
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
19
678
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Измените чтение и запись с помощью W Если вам необходимо использовать WB, используйте следующие функции. Вам нужно добавить r перед всеми текстами, чтобы обрабатывать специальные символы.

import csv
import json

x = r"""[
      {
        "brief": "Brief 1",
        "description": "Description 1",
        "photos": [
          "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example.jpg?0101010101010",
          "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example2.jpg?0101010101010",
          "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example3.jpg?0101010101010"
        ],
        "price": "145",
        "tags": [
          "tag1",
          "tag2",
          "tag3"
        ],
        "title": "Title 1"
      },
      {
        "brief": "Brief 2",
        "description": "Description 2",
        "photos": [
          "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example4.jpg?0101010101010",
          "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example5.jpg?0101010101010"
        ],
        "price": "150",
        "tags": [
          "tag4",
          "tag5",
          "tag6",
          "tag7",
          "tag8"
        ],
        "title": "Title 2"
      },{
        "brief": "blah blah 5'0\" to 5'4\"",
        "buyerPickup": true,
        "condition": "Good",
        "coverShipping": false,    
        "description": "blah blah 5'0\" to 5'4\". blah blah.Size L/20”\n 5’8-5’11\n29lbs\n3x7 speed\n\n  \r\n\r\n",
        "photos": [
          "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-010101.jpeg?11111",
          "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-020202?111111"
        ],
        "price": "240",
        "tags": [
          "tag2",
          "5'0\"-5'4\""
        ],
        "title": "blah blah 17\" Frame",
        "front": "https://firebasestorage.googleapis.com/v0/b/example.appspot.com/o/Images%2F0007891113.jpg?alt=media&token=111-11-11-11-111"    
      } 
    ]"""

x = json.loads(x)


def to_str(bytes_or_str):
    if isinstance(bytes_or_str, bytes):
        value = bytes_or_str.encode('utf-8')
    else:
        value = bytes_or_str
    return value


def to_bytes(bytes_or_str):
    if isinstance(bytes_or_str, str):
        value = bytes_or_str.encode('utf-8')
    else:
        value = bytes_or_str

    return value


f = csv.writer(open("example.csv", "w+"))
writeList = ["Handle", "Title", "Body (HTML)", "Vendor", "Type", "Tags", "Published", "Option1 Name", "Option1 Value",
             "Variant Inventory Qty", "Variant Inventory Policy", "Variant Fulfillment Service", "Variant Price",
             "Variant Requires Shipping", "Variant Taxable", "Image Src"]
newList = []
for item in writeList:
    newList.append(to_bytes(item))

f.writerow(newList)

for x in x:

    allTags = r"\"" + ','.join(x["tags"]) + r"\""
    images = x["photos"]
    f.writerow([x["title"],
                x["title"],
                x["description"],
                "Vendor Name",
                "Widget",
                allTags,
                "TRUE",
                "Title",
                "Default Title",
                "1",
                "deny",
                "manual",
                x["price"],
                "TRUE",
                "TRUE",
                images.pop(0) if images else None])
    while images:
        f.writerow([x["title"], None, None, None, None, None, None, None, None, None, None, None, None, None, None,
                    images.pop(0)])

Это не решает проблему, указанную в вопросе, который является TypeError

Marlon Abeykoon 10.07.2018 10:58
Ответ принят как подходящий

Исходя из ваших опубликованных образцов данных, я предполагаю, что 1-й индекс опубликованного json имеет нулевое значение в 3-м индексе значений ключа tag. т.е. tag7

"tags": [
          "tag4",
          "tag5",
          "tag6",
          "tag7",
          "tag8"
        ],

Чтобы избавиться от TypeError, который возникает из-за нулей, вы можете просто проверить и заменить нули, если они существуют, как показано ниже.

x["tags"] = ["" if i is None else i for i in x["tags"]]
allTags = "\"" + ','.join(x["tags"]) + "\""

Я назначил пустую строку для замены нулей.

В качестве альтернативы вы можете удалить все ложные элементы, используя None в функции filter().

allTags = "\"" + ','.join(filter(None, x["tags"])) + "\""

ПРИМЕЧАНИЕ: добавьте r"[...]" и исправьте проблему отступа в цикле for.

Используйте необработанную строку и установите кодировку файла utf-8 в обычном (небинарном режиме) режиме при открытии. Для Python 3.6 этого будет достаточно.

В Python 2.7 вы должны использовать codecs.open('example.csv', 'w', encoding='utf-8') вместо обычного open() при работе с содержимым Unicode. Кроме того, модуль csv на Python 2.7 не поддерживает Unicode из коробки, поэтому я предлагаю перейти на unicodecsv или следовать рекомендациям в этот ответ.

Возможный дубликат этого вопроса как преобразовать символы типа \ x22 в строку

При очистке кода ошибка сводится к

import json

x = '''
  {
    "brief": "\""
  }'''

x = json.loads(x)

Рассмотрите возможность замены \" на \u201d

import json

x = '{"brief": "\u201d"}'

x = json.loads(x)

Другие вопросы по теме