UnicodeEncodeError: кодек «ascii» не может кодировать символ «\ xb0» в позиции 23: порядковый номер не в диапазоне (128)

Я пытаюсь загрузить изображение по ссылке, содержащей специальный символ, например: imageUrl = 'https://www.residentadvisor.net/images/labels/3000°records.jpg'

request_=urllib.request.Request(imageUrl,None,headers) #The assembled request
print(request_)
response = urllib.request.urlopen(request_) #store the response

но при попытке скачать получаю следующую ошибку:

UnicodeEncodeError: 'ascii' codec can't encode character '\xb0' in position 23: ordinal not in range(128)

Поскольку Traceback было слишком большим для добавления, найдите его по этому адресу:

для отслеживания нажмите здесь

UnicodeEncodeError                        Traceback (most recent call last)
<ipython-input-52-d0b0a8f766c9> in <module>()
    135             request_=urllib.request.Request(imageUrl,None,headers) #The assembled request
    136             print(request_)
--> 137             response = urllib.request.urlopen(request_) #store the response
    138 #create a new file and write the image

    /Users/-/anaconda/lib/python3.6/urllib/request.py in urlopen(url, data, timeout, cafile, capath, cadefault, context)
221     else:
222         opener = _opener
--> 223     return opener.open(url, data, timeout)
224 
225 def install_opener(opener):

/Users/-/anaconda/ lib/python3.6/urllib/request.py in open(self, fullurl, data, timeout)
524             req = meth(req)
525 
--> 526         response = self._open(req, data)
527 
528         # post-process response

/Users/-/anaconda/lib/python3.6/urllib/request.py in _open(self, req, data)
542         protocol = req.type
543         result = self._call_chain(self.handle_open, protocol, protocol +
--> 544                                   '_open', req)
545         if result:
546             return result

/Users/-/anaconda/lib/python3.6/urllib/request.py in _call_chain(self, chain, kind, meth_name, *args)
502         for handler in handlers:
503             func = getattr(handler, meth_name)
--> 504             result = func(*args)
505             if result is not None:
506                 return result

/Users/-/anaconda/lib/python3.6/urllib/request.py in https_open(self, req)
1359         def https_open(self, req):
1360             return self.do_open(http.client.HTTPSConnection, req,
-> 1361                 context=self._context, check_hostname=self._check_hostname)
1362 
1363         https_request = AbstractHTTPHandler.do_request_

/Users/-/anaconda/lib/python3.6/urllib/request.py in do_open(self, http_class, req, **http_conn_args)
1316             try:
1317                 h.request(req.get_method(), req.selector, req.data, headers,
-> 1318                           encode_chunked=req.has_header('Transfer-encoding'))
1319             except OSError as err: # timeout error
1320                 raise URLError(err)

/Users/-/anaconda/lib/python3.6/http/client.py in request(self, method, url, body, headers, encode_chunked)
1237                 encode_chunked=False):
1238         """Send a complete request to the server."""
-> 1239         self._send_request(method, url, body, headers, encode_chunked)
1240 
1241     def _send_request(self, method, url, body, headers, encode_chunked):

/Users/-/anaconda/lib/python3.6/http/client.py in _send_request(self, method, url, body, headers, encode_chunked)
1248             skips['skip_accept_encoding'] = 1
1249 
-> 1250         self.putrequest(method, url, **skips)
1251 
1252         # chunked encoding will happen if HTTP/1.1 is used and either

/Users/-/anaconda/lib/python3.6/http/client.py in putrequest(self, method, url, skip_host, skip_accept_encoding)
1115 
1116         # Non-ASCII characters should have been eliminated earlier
-> 1117         self._output(request.encode('ascii'))
1118 
1119         if self._http_vsn == 11:

UnicodeEncodeError: 'ascii' codec can't encode character '\xb0' in position 23: ordinal not in range(128)

person anho    schedule 13.07.2017    source источник
comment
Почему вы говорите, что трассировка слишком велика? Копирование/вставка должны работать нормально. Я не собираюсь нажимать на случайную интернет-ссылку только для того, чтобы увидеть важную информацию по вашему вопросу.   -  person Mark Ransom    schedule 13.07.2017
comment
потому что я не могу опубликовать вопрос в текущей форме со всей трассировкой ... s/o говорит мне добавить больше текста, так как это кажется только кодом, если я отформатирую трассировку   -  person anho    schedule 13.07.2017
comment
я мог бы добавить его как изображение, если вы хотите?   -  person anho    schedule 13.07.2017
comment
Идите вперед и добавьте текст без форматирования, и кто-то придет и отформатирует его для вас. Глупый SO и их попытки навязать качество контента слишком часто приводят к неприятным последствиям.   -  person Mark Ransom    schedule 13.07.2017
comment
теперь, получая сообщение «Похоже, что сообщение содержит код, который неправильно отформатирован ...», я попытаюсь сделать это по-другому.   -  person anho    schedule 13.07.2017
comment
@MarkRansom как-то сработало :) ... я добавил трассировку   -  person anho    schedule 13.07.2017
comment
Вау, я никогда не использовал IPython — он включает гораздо больше контекста в трассировку, чем я привык. Я бы попробовал использовать строку Unicode в вызове urlopen, как это было предложено удаленным ответом.   -  person Mark Ransom    schedule 13.07.2017


Ответы (1)


urllib.request ожидает правильного экранированного URL-адреса.

В этом случае правильно экранированный URL-адрес:

imageUrl = 'https://www.residentadvisor.net/images/labels/3000%C2%B0records.jpg'

Если вы имеете дело с потенциально плохо закодированными URL-адресами, одна библиотека, которая поможет вам правильно закодировать их, — это yelp_uri.encoding.recode_uri. Полное раскрытие: я внес свой вклад в эту библиотеку.

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

from yelp_uri.encoding import recode_uri
imageUrl = recode_uri(imageUrl)
person Anthony Sottile    schedule 13.07.2017
comment
спасибо за раскрытие и библиотеку ... работает как шарм ;) - person anho; 13.07.2017