Уведомления

Группа в Telegram: @pythonsu

#1 Авг. 11, 2013 08:54:24

shau-kote
Зарегистрирован: 2013-02-17
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

Умлаут в url и requests

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

Столкнулся я со следующей проблемой - requests не может загрузить страницу, в url которой есть умлаут:

resp = requests.get('http://irr.ru/electronics-technics/ironing-sewing-equipment/sewing-machines/Prodam-shveynaya-mashinka-K%C3%B6hler-11-30-advert277603897.html')
---------------------------------------------------------------------------
TooManyRedirects                          Traceback (most recent call last)
<ipython-input-12-67230f7ebce4> in <module>()
----> 1 resp = requests.get('http://irr.ru/electronics-technics/ironing-sewing-equipment/sewing-machines/Prodam-shveynaya-mashinka-K%C3%B6hler-11-30-advert277603897.html')
C:\Dev\Python32\lib\site-packages\requests\api.py in get(url, **kwargs)
     53 
     54     kwargs.setdefault('allow_redirects', True)
---> 55     return request('get', url, **kwargs)
     56 
     57 
C:\Dev\Python32\lib\site-packages\requests\api.py in request(method, url, **kwargs)
     42 
     43     session = sessions.Session()
---> 44     return session.request(method=method, url=url, **kwargs)
     45 
     46 
C:\Dev\Python32\lib\site-packages\requests\sessions.py in request(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert)
    333             'allow_redirects': allow_redirects,
    334         }
--> 335         resp = self.send(prep, **send_kwargs)
    336 
    337         return resp
C:\Dev\Python32\lib\site-packages\requests\sessions.py in send(self, request, **kwargs)
    452 
    453         # Resolve redirects if allowed.
--> 454         history = [resp for resp in gen] if allow_redirects else []
    455 
    456         # Shuffle things around if there's history.
C:\Dev\Python32\lib\site-packages\requests\sessions.py in <listcomp>(.0)
    452 
    453         # Resolve redirects if allowed.
--> 454         history = [resp for resp in gen] if allow_redirects else []
    455 
    456         # Shuffle things around if there's history.
C:\Dev\Python32\lib\site-packages\requests\sessions.py in resolve_redirects(self, resp, req, stream, timeout, verify, cert, proxies)
     85 
     86             if i >= self.max_redirects:
---> 87                 raise TooManyRedirects('Exceeded %s redirects.' % self.max_redirects)
     88 
     89             # Release the connection back into the pool.
TooManyRedirects: Exceeded 30 redirects.
Сама злополучная страница, собственно, вот.

Оставляю в стороне вопрос того, насколько вообще хорошо использовать в url умлаут, так как проблему в requests это не особо оправдывает.
Впрочем, страницы с кириллическими url requests как-то без проблем загружает.

Подскажите, пожалуйста, как можно решить эту проблему?

Офлайн

#2 Авг. 11, 2013 22:07:57

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

Умлаут в url и requests

В Python 2.7 работает нормально. В 3.3 такая же ошибка. И похоже она не в requests, а в стандартной библиотеке http/client.py parse_headers() или в ответе сервера (это RFC нужно глянуть).
В заголовке Location приходит строка в utf-8, а parse_headers() в 3.3 декодирует ее из iso-8859-1.

С urllib тоже не работает на 3.3:

try:
    from urllib import request as urllib
except ImportError:
    import urllib
url = 'http://irr.ru/electronics-technics/ironing-sewing-equipment/sewing-machines/Prodam-shveynaya-mashinka-K%C3%B6hler-11-30-advert277603897.html'
r = urllib.urlopen(url)

Офлайн

#3 Авг. 12, 2013 15:54:31

lorien
От:
Зарегистрирован: 2006-08-20
Сообщения: 755
Репутация: +  37  -
Профиль  

Умлаут в url и requests

>>> from grab import Grab
>>> g = Grab()
>>> g.go('http://irr.ru/electronics-technics/ironing-sewing-equipment/sewing-machines/Prodam-shveynaya-mashinka-K%C3%B6hler-11-30-advert277603897.html')
<grab.response.Response object at 0xf970f8>
>>> print g.doc.select('//title').text()
Продам: швейная машинка Köhler 11-30, Москва - IRR.ru

Офлайн

#4 Авг. 17, 2013 16:29:10

shau-kote
Зарегистрирован: 2013-02-17
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

Умлаут в url и requests

Извиняюсь за долгое молчание.

Получается, это-таки баг, но не в requests, а в urllib?

lorien, спасибо за совет, но не хотелось бы прикручивать довольно большую библиотеку для простой загрузки страниц.
И мне очень интересно, почему Grab работает нормально, а requests - нет, хотя они обе вроде построены на одних и тех же стандартных библиотеках?

Офлайн

#5 Авг. 17, 2013 16:43:51

lorien
От:
Зарегистрирован: 2006-08-20
Сообщения: 755
Репутация: +  37  -
Профиль  

Умлаут в url и requests

И мне очень интересно, почему Grab работает нормально, а requests - нет, хотя они обе вроде построены на одних и тех же стандартных библиотеках?
Если очень интересно, смотрите исходный код библиотек и разбирайтесь, почему оно так, как есть.
Нет, Grab и requests используют разные сетевые библиотеки, и оне не стандартные.
Grab использует pycurl
requests использует urllib3, если не ошибаюсь

Офлайн

#6 Авг. 17, 2013 16:58:20

shau-kote
Зарегистрирован: 2013-02-17
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

Умлаут в url и requests

lorien, уже заметил, спасибо.

Ладно, попробую заменить requests pycurl'ом.

Спасибо всем за помощь.

UPD
Скажите, а какие вообще есть альтернативы requests?
Хотел вот переписать свой код под pycurl, но его нет под Py3. Да и интерфейс его, мягко говоря, оставляет желать лучшего (для моих целей).
Хотелось бы что-нибудь, что как request позволяет сделать get(url) и получить потом код HTTP и текст ответа.
Есть что-нибудь такое?

Отредактировано shau-kote (Авг. 17, 2013 22:15:19)

Офлайн

#7 Авг. 18, 2013 08:37:43

ring0za
Зарегистрирован: 2012-08-13
Сообщения: 18
Репутация: +  1  -
Профиль   Отправить e-mail  

Умлаут в url и requests

аа там вродьбы httpie еще был - подобие curl

Офлайн

#8 Авг. 18, 2013 15:13:54

lorien
От:
Зарегистрирован: 2006-08-20
Сообщения: 755
Репутация: +  37  -
Профиль  

Умлаут в url и requests

Скажите, а какие вообще есть альтернативы requests?
Хотел вот переписать свой код под pycurl, но его нет под Py3. Да и интерфейс его, мягко говоря, оставляет желать лучшего (для моих целей).
Хотелось бы что-нибудь, что как request позволяет сделать get(url) и получить потом код HTTP и текст ответа.
Есть что-нибудь такое?

Альтернатива есть: http://grablib.org
Он работает в том числе под py3k. Использует pycurl.
Об этом не все знают, но pycurl работает под py3k. В ubuntu его можно поставить прямо через apt
В других системах можно поставить через pip отсюда: https://github.com/lorien/pycurl
Один нюанс, py3 должен быть версии 3.3 (под 3.2 и 3.1 Grab не будет работать)

Офлайн

#9 Авг. 18, 2013 17:38:13

shau-kote
Зарегистрирован: 2013-02-17
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

Умлаут в url и requests

lorien, я на него смотрел, приятный фреймворк, но в документации чётко сказано “Grab is developed for python 2.x environment. It does not support py3k yet.”

Офлайн

#10 Авг. 18, 2013 18:14:50

lorien
От:
Зарегистрирован: 2006-08-20
Сообщения: 755
Репутация: +  37  -
Профиль  

Умлаут в url и requests

Документация устарела. Сейчас Grab работает под python 3, все тесты выполняются.

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version