Requests: UnicodeEncodeError: 'latin-1'コーデックは文字をエンコードできません

作成日 2013年12月20日  ·  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 Text3はPython2.7(Sublime Text 2が使用)ではなくPython3.3を使用します。 これは、SublimeApexのデフォルトの文字列がすべて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がリクエストにユニコード文字列本体を提供していることです。これは、httplibがバイトにエンコードする必要があります。 RFC 2616のデフォルトを使用すると、漢字を含まないLatin-1が必要であると結論付けられます。 明らかに、エンコードは失敗し、問題の例外が発生します。

Sublime Apexが送信するヘッダーで、UTF-8でエンコードされたデータ(現在は嘘です)を送信していると主張していることを考えると、Sublime Apexは、送信する前にデータをUTF-8としてエンコードしたいと考えています。 つまり、データを送信する行(この場合はsalesforce/api.py行545)は次のようになります。

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 (またはPython 3ではhttpから上昇しているように見えます。

@ sigmavirus24

私は崇高なプラグインでリクエストを使用しました。以下のステートメントのsoap_bodyに漢字が含まれていなかった場合、例外はありません。

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

まず、パブリックリポジトリにあるものとは異なるバージョンのSublime Apexを使用していない限り、Requestsは最新バージョンではなくバージョン1.2.3です。 使用しているSublimeTextのバージョンを教えてください。

それは崇高なテキスト3056です

したがって、ST 3ですが、最新のリビジョンではありません。 わかりました、それは私たちに何かを与えます。 具体的には、Sublime Text3はPython2.7(Sublime Text 2が使用)ではなくPython3.3を使用します。 これは、SublimeApexのデフォルトの文字列がすべて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がリクエストにユニコード文字列本体を提供していることです。これは、httplibがバイトにエンコードする必要があります。 RFC 2616のデフォルトを使用すると、漢字を含まないLatin-1が必要であると結論付けられます。 明らかに、エンコードは失敗し、問題の例外が発生します。

Sublime Apexが送信するヘッダーで、UTF-8でエンコードされたデータ(現在は嘘です)を送信していると主張していることを考えると、Sublime Apexは、送信する前にデータをUTF-8としてエンコードしたいと考えています。 つまり、データを送信する行(この場合はsalesforce/api.py行545)は次のようになります。

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 評価