Requests: UnicodeEncodeError: кодек latin-1 не может кодировать символы

Созданный на 20 дек. 2013  ·  7Комментарии  ·  Источник: psf/requests

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

Traceback (most recent call last):
  File "X/threading.py", line 639, in _bootstrap_inner
  File "X/threading.py", line 596, in run
  File "C:\Users\Administrator\Dropbox\Sublime3056\Data\Packages\SublimeApex\salesforce\api.py", line 546, in execute_anonymous
    headers=headers)
  File "C:\Users\Administrator\Dropbox\Sublime3056\Data\Packages\SublimeApex\requests\api.py", line 88, in post
    return request('post', url, data=data, **kwargs)
  File "C:\Users\Administrator\Dropbox\Sublime3056\Data\Packages\SublimeApex\requests\api.py", line 44, in request
    return session.request(method=method, url=url, **kwargs)
  File "C:\Users\Administrator\Dropbox\Sublime3056\Data\Packages\SublimeApex\requests\sessions.py", line 338, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Users\Administrator\Dropbox\Sublime3056\Data\Packages\SublimeApex\requests\sessions.py", line 441, in send
    r = adapter.send(request, **kwargs)
  File "C:\Users\Administrator\Dropbox\Sublime3056\Data\Packages\SublimeApex\requests\adapters.py", line 292, in send
    timeout=timeout
  File "C:\Users\Administrator\Dropbox\Sublime3056\Data\Packages\SublimeApex\requests\packages\urllib3\connectionpool.py", line 428, in urlopen
    body=body, headers=headers)
  File "C:\Users\Administrator\Dropbox\Sublime3056\Data\Packages\SublimeApex\requests\packages\urllib3\connectionpool.py", line 280, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "X/http/client.py", line 1049, in request
  File "X/http/client.py", line 1086, in _send_request
UnicodeEncodeError: 'latin-1' codec can't encode characters in position 1632-1633: ordinal not in range(256)

Самый полезный комментарий

Итак, ST 3, но не самая последняя ревизия. Хорошо, это дает нам кое-что. В частности, Sublime Text 3 использует Python 3.3, а не Python 2.7 (который использовал Sublime Text 2). Это означает, что все строки по умолчанию в Sublime Apex являются строками Unicode.

Если вы откроете файл Python 3.3 http.client , вы обнаружите, что функция _send_request() выглядит так:

# Honor explicitly requested Host: and Accept-Encoding: headers.
header_names = dict.fromkeys([k.lower() for k in headers])
skips = {}
if 'host' in header_names:
    skips['skip_host'] = 1
if 'accept-encoding' in header_names:
    skips['skip_accept_encoding'] = 1

self.putrequest(method, url, **skips)

if body is not None and ('content-length' not in header_names):
    self._set_content_length(body)
for hdr, value in headers.items():
    self.putheader(hdr, value)
if isinstance(body, str):
    # RFC 2616 Section 3.7.1 says that text default has a
    # default charset of iso-8859-1.
    body = body.encode('iso-8859-1')
self.endheaders(body)

Теперь ISO-8859-1 - это псевдоним для Latin-1, кодека, с которым у нас возникли проблемы. Проблема в том, что Sublime Apex предоставляет запросам тело строки Unicode, которое httplib необходимо кодировать в байты. Принимая значение по умолчанию из RFC 2616, он приходит к выводу, что вам нужен Latin-1, который не включает никаких китайских символов. Очевидно, что кодирование не выполняется, и вы получаете рассматриваемое исключение.

Учитывая, что Sublime Apex утверждает в отправляемых им заголовках для отправки данных в кодировке UTF-8 (что в настоящее время является ложью), Sublime Apex хочет кодировать данные как UTF-8 перед их отправкой. Это означает, что любая строка, отправляющая данные (в данном случае строка 545 из salesforce/api.py ) должна читаться следующим образом:

response = requests.post(self.apex_url, soap_body.encode('utf-8'), verify=False, headers=headers)

Ради всех, кто хочет подтвердить мой диагноз, вот небольшой пример кода, который подтверждает проблему:

a = "\u13E0\u19E0\u1320"
a.encode('latin1')  # Throws UnicodeEncodeError, proves that this can't be expressed in ISO-8859-1.
a.encode('utf-8')  # Totally fine.
r = requests.post('http://httpbin.org/post', data=a)  # Using unicode string, throws UnicodeEncodeError blaming Latin1.
r = requests.post('http://httpbin.org/post', data=a.encode('utf-8'))  # Works fine.

Спасибо, что подняли этот вопрос, но это не ошибка запросов. знак равно

Все 7 Комментарий

Файл "X / http / client.py"

Вы написали X потому что это путь к локальному файлу? Если это так, ваша структура каталогов может сбивать с толку urllib3. Если нет, то вам, вероятно, следует поднять этот вопрос с помощью bugs.python.org, поскольку я думаю, что это не то, что должны обрабатывать запросы. Похоже, это происходит от httplib (или http на Python 3, который, как я предполагаю, вы используете).

@ sigmavirus24 ,

Я использовал запросы в sublime plugin, если мыло_body в приведенном ниже заявлении не содержит китайских иероглифов, исключений не будет.

response = requests.post(self.apex_url, soap_body, verify=False, headers=headers)

Во-первых, если вы не используете версию Sublime Apex, отличную от версии в их общедоступном репозитории, Requests _не_ последняя версия, это версия 1.2.3. Можете ли вы сказать мне, какую версию Sublime Text вы используете?

Это возвышенный текст 3056

Итак, ST 3, но не самая последняя ревизия. Хорошо, это дает нам кое-что. В частности, Sublime Text 3 использует Python 3.3, а не Python 2.7 (который использовал Sublime Text 2). Это означает, что все строки по умолчанию в Sublime Apex являются строками Unicode.

Если вы откроете файл Python 3.3 http.client , вы обнаружите, что функция _send_request() выглядит так:

# Honor explicitly requested Host: and Accept-Encoding: headers.
header_names = dict.fromkeys([k.lower() for k in headers])
skips = {}
if 'host' in header_names:
    skips['skip_host'] = 1
if 'accept-encoding' in header_names:
    skips['skip_accept_encoding'] = 1

self.putrequest(method, url, **skips)

if body is not None and ('content-length' not in header_names):
    self._set_content_length(body)
for hdr, value in headers.items():
    self.putheader(hdr, value)
if isinstance(body, str):
    # RFC 2616 Section 3.7.1 says that text default has a
    # default charset of iso-8859-1.
    body = body.encode('iso-8859-1')
self.endheaders(body)

Теперь ISO-8859-1 - это псевдоним для Latin-1, кодека, с которым у нас возникли проблемы. Проблема в том, что Sublime Apex предоставляет запросам тело строки Unicode, которое httplib необходимо кодировать в байты. Принимая значение по умолчанию из RFC 2616, он приходит к выводу, что вам нужен Latin-1, который не включает никаких китайских символов. Очевидно, что кодирование не выполняется, и вы получаете рассматриваемое исключение.

Учитывая, что Sublime Apex утверждает в отправляемых им заголовках для отправки данных в кодировке UTF-8 (что в настоящее время является ложью), Sublime Apex хочет кодировать данные как UTF-8 перед их отправкой. Это означает, что любая строка, отправляющая данные (в данном случае строка 545 из salesforce/api.py ) должна читаться следующим образом:

response = requests.post(self.apex_url, soap_body.encode('utf-8'), verify=False, headers=headers)

Ради всех, кто хочет подтвердить мой диагноз, вот небольшой пример кода, который подтверждает проблему:

a = "\u13E0\u19E0\u1320"
a.encode('latin1')  # Throws UnicodeEncodeError, proves that this can't be expressed in ISO-8859-1.
a.encode('utf-8')  # Totally fine.
r = requests.post('http://httpbin.org/post', data=a)  # Using unicode string, throws UnicodeEncodeError blaming Latin1.
r = requests.post('http://httpbin.org/post', data=a.encode('utf-8'))  # Works fine.

Спасибо, что подняли этот вопрос, но это не ошибка запросов. знак равно

Спасибо.

r = requests.post (' http://httpbin.org/post ', data = a.encode ('utf-8'))
очень полезно,
благодарю вас!

Была ли эта страница полезной?
0 / 5 - 0 рейтинги