Вопрос:

Кодек 'ascii' не может закодировать символ: порядковый номер не в диапазоне (128)

python json selenium utf-8 beautifulsoup

840 просмотра

2 ответа

379 Репутация автора

Я очищаю некоторые веб-страницы, используя селен и 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')

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

Автор: DiamondJoe12 Источник Размещён: 12.05.2019 11:49

Ответы (2)


4 плюса

155274 Репутация автора

Ваша проблема в том, что в 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()ничего не возвращает; вместо этого он записывает содержимое непосредственно в файл. (Если бы не было никакого текста Unicode item, это 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)
    
Автор: duskwuff Размещён: 13.05.2019 01:18

0 плюса

6754 Репутация автора

Возможно, вам придется установить PYTHONIOENCODING перед запуском скрипта Python в оболочке. Например, я получил ту же ошибку при перенаправлении вывода скрипта python в файл журнала:

$ your_python_script > output.log
'ascii' codec can't encode characters in position xxxxx-xxxxx: ordinal not in range(128)

После изменения PYTHONIOENCODING на UTF8 в оболочке скрипт выполняется без ошибки кодека ASCII:

$ export PYTHONIOENCODING=utf8

$ your_python_script > output.log
Автор: Noam Manos Размещён: 11.08.2019 08:46
Вопросы из категории :
32x32