Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 18, 2012 12:54:13

ustuz
От:
Зарегистрирован: 2011-05-02
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

urlopen и кириллические URL

Всем доброго времени суток!

Возникла проблема, на решая которую потратил вот уже несколько часов.
Суть примерно следующая.

Есть url, содержащий кириллические символы. Например: http://спортмат.рф/products/Спортмат_Детский_мат_500х500х50_мм
Необходимо открыть данный url при помощи urlopen

Делаю так:

from urllib2 import urlopen

url=u"http://спортмат.рф/products/Спортмат_Детский_мат_500х500х50_мм"
a = urlopen(url)
Получаю ошибку:

Traceback (most recent call last):
File “<pyshell#13>”, line 1, in <module>
urlopen(url)
File “C:\Python27\lib\urllib2.py”, line 126, in urlopen
return _opener.open(url, data, timeout)
File “C:\Python27\lib\urllib2.py”, line 394, in open
response = self._open(req, data)
File “C:\Python27\lib\urllib2.py”, line 412, in _open
‘_open’, req)
File “C:\Python27\lib\urllib2.py”, line 372, in _call_chain
result = func(*args)
File “C:\Python27\lib\urllib2.py”, line 1199, in http_open
return self.do_open(httplib.HTTPConnection, req)
File “C:\Python27\lib\urllib2.py”, line 1168, in do_open
h.request(req.get_method(), req.get_selector(), req.data, headers)
File “C:\Python27\lib\httplib.py”, line 955, in request
self._send_request(method, url, body, headers)
File “C:\Python27\lib\httplib.py”, line 988, in _send_request
self.putheader(hdr, value)
File “C:\Python27\lib\httplib.py”, line 935, in putheader
hdr = ‘%s: %s’ % (header, ‘\r\n\t’.join())
UnicodeEncodeError: ‘ascii’ codec can't encode characters in position 0-7: ordinal not in range(128)


Подскажите, плиз, как открыть подобный URL с помощью urlopen?



Офлайн

#2 Янв. 18, 2012 13:49:59

agalen
От:
Зарегистрирован: 2011-03-23
Сообщения: 185
Репутация: +  17  -
Профиль   Отправить e-mail  

urlopen и кириллические URL

urlopen требует только латинские буквы.
Преобразовать можно так:

import re, urlparse

def urlEncodeNonAscii(b):
return re.sub('[\x80-\xFF]', lambda c: '%%%02x' % ord(c.group(0)), b)

def iriToUri(iri):
parts= urlparse.urlparse(iri)
return urlparse.urlunparse(
part.encode('idna') if parti==1 else urlEncodeNonAscii(part.encode('utf-8'))
for parti, part in enumerate(parts)
)

>>> iriToUri( u"http://спортмат.рф/products/Спортмат_Детский_мат_500х500х50_мм" )
'http://xn--80axfdgdkc.xn--p1ai/products/%d0%a1%d0%bf%d0%be%d1%80%d1%82%d0%bc%d0%b0%d1%82_%d0%94%d0%b5%d1%82%d1%81%d0%ba%d0%b8%d0%b9_%d0%bc%d0%b0%d1%82_500%d1%85500%d1%8550_%d0%bc%d0%bc'



Офлайн

#3 Янв. 19, 2012 22:55:59

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9846
Репутация: +  853  -
Профиль   Отправить e-mail  

urlopen и кириллические URL

для питона 2.7 нужно объявлять кодировку в начале исходного файла, если в скрипте есть символы, не входящие в ascii

>>> import urllib
>>> s = u'http://www.site.com/абвг/defg'
>>> s
u'http://www.site.com/\u0430\u0431\u0432\u0433/defg'
>>> t = urllib.splittype(s)
>>> es = u':'.join((t[0], urllib.quote(t[1].encode('utf-8'))))
>>> es
u'http://www.site.com/%D0%B0%D0%B1%D0%B2%D0%B3/defg'
>>>
>>> import urllib
>>> s = u'http://www.site.com/абвг/defg'
>>> s
u'http://www.site.com/\u0430\u0431\u0432\u0433/defg'
>>> t = urllib.splittype(s)
>>> es = t[0] + u':' + urllib.quote(t[1].encode('utf-8'))
>>> es
u'http://www.site.com/%D0%B0%D0%B1%D0%B2%D0%B3/defg'
>>>
она там двоеточие тоже кодирует, если без разделения делать



Отредактировано (Янв. 19, 2012 23:13:01)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version