UnicodeEncodeError AND TypeError: может объединять только str (но не «байты») в str - PullRequest
0 голосов
/ 07 апреля 2019

У меня есть проблема, и я пытаюсь найти результаты с помощью API пользовательского поиска Google для python, но когда я ищу вещи, которые хранятся в varibale, вместо того, чтобы писать их вручную, он говорит, что кодек UnicodeEncodeError: 'ascii' может'кодировать символ' \ xa2 'в позиции 104: порядковый номер не в диапазоне (128).Когда я решаю его с помощью

    .encode('ascii', 'ignore').decode('ascii')  

, появляется другая ошибка, например, пользовательский поиск Google

    TypeError: can only concatenate str (not "bytes") to str.

PD: я также пробовал что-то, например str () или .decodeодин.

Редактировать: Конечно, входные данные, которые хранятся в переменных, взяты из Pytesseract, который читает текст изображения.Поэтому я сохраняю эту информацию в переменной, а затем пытаюсь найти эту информацию в API пользовательского поиска Google.Поскольку он отображал ошибку Unicode, я посмотрел в stackoverflow решение и обнаружил, что могу попытаться расшифровать переменную, чтобы больше не было этой проблемы.Фактически эта проблема была решена, но теперь появилась другая, и это та же ошибка TypeError: можно объединить только str (не "байты") в str.Итак, я не могу использовать функцию .decode, потому что она покажет другую ошибку.Что я могу сделать?

Редактировать 2.0

text_photo = pytesseract.image_to_string(img2) #this will read the text and put it in a variable
text_photo = text_photo.replace('\r', '').replace('\n', '') #this will elimininate de /n


rawData = urllib.request.urlopen(url_google_1 + text_photo1 + '+' + text_photo2 + url_google_2).read() 

url_google 1, связывающий первую часть ссылки (ключ api ...) для поиска в Google, а вторая содержит то, что я хочучтобы получить от Google.В середине я добавляю переменную, потому что это то, что я хочу искать.Если я пишу привет, это работает отлично, проблема в том, что формат, который пишет tesseract не совместим, я попытался использовать str (text_photo) и .decode, но не работает json_data = json.loads (rawData)

1 Ответ

0 голосов
/ 07 апреля 2019

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

Python 3 различает два типа строк, str и bytes, которые похожи, но несовместимы.

Как только вы поймете, что это означает, что каждый из них может / не может делать и как переходить от одного к другому, я уверен, что вы сможете понять, как правильно построить URL для вызова API.

Различные типы, несовместимые:

>>> type('abc'), type(b'abc')
(<class 'str'>, <class 'bytes'>)

>>> 'abc' + b'abc'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: must be str, not bytes

>>> b'abc' + 'abc'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't concat str to bytes

Если вы хотите объединить их, вам нужно преобразовать все в один и тот же тип. Для преобразования кодируйте str в bytes, декодируйте bytes в str:

>>> 'abc'.encode()
b'abc'
>>> b'abc'.decode()
'abc'

Методы str.encode и bytes.decode принимают необязательный параметр encoding=, который по умолчанию равен UTF-8. Этот параметр определяет отображение между символами в str и октетами в bytes объекте. Если существует проблема с отображением символов в байты с заданной кодировкой, вы увидите UnicodeEncodeError. Это происходит, если вы используете символ, который не определен в данном отображении:

>>> '5 £'.encode('ascii')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character '\xa3' in position 2: ordinal not in range(128)

Аналогично, если какой-то текст был закодирован с кодировкой X, но вы пытаетесь декодировать его с кодировкой Y, вы можете увидеть UnicodeDecodeError:

>>> b = '5 £'.encode('utf8')
>>> b
b'5 \xc2\xa3'
>>> b.decode('ascii')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 2: ordinal not in range(128)

Вы можете избежать исключения с помощью стратегии errors="ignore", но вы потеряете информацию таким образом:

>>> '5 £'.encode('ascii', errors='ignore')
b'5 '

Как правило, если вы работаете с текстом, вы используете str везде. Вам также не нужно часто использовать .encode/.decode напрямую; часто обработчики файлов и т. д. принимают str и преобразуют их в bytes за сценой.

В вашем случае вам нужно выяснить, где и почему у вас есть смесь str и bytes, а затем убедиться, что все имеют один и тот же тип, прежде чем объединять.

...