Кодек 'ascii' не может закодировать символ: порядковый номер не в диапазоне (128) - PullRequest
0 голосов
/ 13 мая 2019

Я очищаю некоторые веб-страницы, используя селен и BeautifulSoup. Я перебираю кучу ссылок, собираю информацию и затем выгружаю ее в JSON:

for event in events:

    case = {'Artist': item['Artist'], 'Date': item['Date'], 'Time': item['Time'], 'Venue': item['Venue'],
        'Address': item['Address'], 'Coordinates': item['Coordinates']}
    item[event] = case

with open("testScrape.json", "w") as writeJSON:
json.dump(item, writeJSON, ensure_ascii=False)

Когда я получаю по этой ссылке: https://www.bandsintown.com/e/100778334-jean-deaux-music-at-rickshaw-stop?came_from=257&utm_medium=web&utm_source=home&utm_campaign=event

Код ломается, и я получаю следующую ошибку:

 Traceback (most recent call last):
  File "/Users/s/PycharmProjects/hi/BandsintownWebScraper.py", line 126, in <module>
    json.dump(item, writeJSON, ensure_ascii=False)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 190, in dump
    fp.write(chunk)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe6' in position 7: ordinal not in range(128)

Я пытался использовать:

json.dump(item, writeJSON, ensure_ascii=False).decode('utf-8')

И

json.dump(item, writeJSON, ensure_ascii=False).encode('utf-8')

Безуспешно. Я полагаю, что именно символ ссылки приводит к сбою. Кто-нибудь может дать краткое описание того, что происходит, что означает кодирование / декодирование и как решить эту проблему? Заранее спасибо.

1 Ответ

4 голосов
/ 13 мая 2019

Ваша проблема в том, что в Python 2 объект file (возвращаемый open()) может записывать только str объекты, но не unicode объекты.Передача ensure_ascii=False в json.dump() заставляет его пытаться записать строки Unicode в файл напрямую как unicode объекты, что приведет к ошибке.

json.dump(item, writeJSON, ensure_ascii=False).encode('utf-8')

Это попытка исправить неработать, потому что json.dump() ничего не возвращает;вместо этого он записывает содержимое непосредственно в файл.(Если бы в item не было текста Unicode, он завершился бы аварийно после завершения json.dump() - json.dump() вернет None, что не может вызывать .encode().)

Естьтри способа исправить это:

  1. Использовать Python 3. Объединение str и unicode в Python 3 делает ваш существующий код работающим как есть;никаких изменений кода не требуется.

  2. Удалите ensure_ascii=False из вашего звонка на json.dump.Символы, не входящие в ASCII, будут записаны в файл в экранированном виде - например, ï будет записано как \u00ef.Это совершенно правильный способ представления символов Unicode, и большинство библиотек JSON справятся с этим просто отлично.

  3. Оберните объект file в UTF-8 StreamWriter:

    import codecs
    with codecs.getwriter("utf8")(open("testScrape.json", "w")) as writeJSON:
        json.dump(item, writeJSON, ensure_ascii=False)
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...