Уведомления

Группа в Telegram: @pythonsu

#1 Ноя. 26, 2013 17:59:35

volframka
Зарегистрирован: 2013-11-26
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

urllib2 askii

python2.7, xubuntu
Сталкнулся с тривиальной, на первый взгляд, проблемой, но уже 5 часов не могу ее решить…Облазил кучу форумов. очень много где встречается данная проблема, но решения нигде не нашел.
Итак код следующий:

# -*- coding: utf-8 -*-
# -*- coding: 'utf-8' -*- 
from __future__ import unicode_literals 
from xml.dom.minidom import Document
import urllib2
import StringIO
import gzip
def do_request(request):
    data = request
    data = unicode(data, "utf-8")
    connection = urllib2.build_opener()
    connection.addheaders = [('WebKey', '123'),
                             ('Content-Length', len(request)),
                             ('Accept-Charset', 'utf-8')]
    #response = unicode(connection.open("http://не_скажу/?OperationType=0", data) , "utf-8")
    response = connection.open("http://не_скажу/?OperationType=1", data).decode('utf-8')
    #return response.data()
    #return response.info()
    return str(response)
    if response.info().get('Content-Encoding') == 'gzip':
        buf = StringIO.StringIO( response.read())
        gzip_f = gzip.GzipFile(fileobj=buf)
        content = gzip_f.read()
    else:
        content = response.read()
    return content

Ошибка стандартная: ‘ascii’ codec can't encode characters in position 98-106: ordinal not in range(128)

От себя добавлю, что именно 98-106 идут русские буквы.
Сервер мне должен отправлять в кодировке UTF-8 (покрайней мере они мне так написали)
Я делал много разных вариаций. Заголовки он мне посмотреть не дает - та же ошибка. Валится именно да операции: connection.open("http/не_скажу/?OperationType=1", data) - и преобразовать в unicode никак не получается.
Кто что подскажет?

Офлайн

#2 Ноя. 26, 2013 18:59:17

bw
От:
Зарегистрирован: 2007-09-26
Сообщения: 938
Репутация: +  20  -
Профиль   Адрес электронной почты  

urllib2 askii

Чудак человек, передаёт `unicode` в качестве данных вот уже 5 часов, замучил бедный интерпретатор, никак не хочет читать его "can't encode" (поясняю, это операция unicode->str). Ну блин, А и Б сложить.

И что это за open(…).decode(…)? Ещё пять часов будем искать причину новой ошибки? API не читай @ код пиши :-).

p.s. Марш читать документацию по `urllib2`, особое вниманием уделяем типам передаваемых аргументов и получаемых результатов и ничего не придумываем сами, в частности, относительного того, что должен возвращать `urllib2.OpenerDirector.open`.

..bw



Отредактировано bw (Ноя. 26, 2013 19:01:54)

Офлайн

#3 Ноя. 26, 2013 19:02:11

Budulianin
От:
Зарегистрирован: 2011-10-18
Сообщения: 1218
Репутация: +  33  -
Профиль   Отправить e-mail  

urllib2 askii

volframka
Ошибка стандартная: ‘ascii’ codec can't encode characters in position 98-106: ordinal not in range(128)

Нужно ПОЛНЫЙ stack trace ошибки писать, а не последнюю строку.

у тебя в data есть не ascii символы.

volframka
connection.open("http://не_скажу/?OperationType=1", data).decode('utf-8')

read() пропустил

bw, прав :)



Отредактировано Budulianin (Ноя. 26, 2013 19:47:14)

Офлайн

#4 Ноя. 27, 2013 09:35:44

volframka
Зарегистрирован: 2013-11-26
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

urllib2 askii

Спасибо, что ответили. Только прошу, в дальнейшем, не общаться со мной, как с неким школьником…

Budulianin
Нужно ПОЛНЫЙ stack trace ошибки писать, а не последнюю строку.
Извини, но разумно ли, отключать демонизацию, убирать исключения далеко не в одном месте в огромной системе, если и так понятно, что ошибка в кодировке?
Это сообщение из лога.
Budulianin
read() пропустил
не пропускал, просто уже опустил.
Я привел код, после многочисленных “умных”сообщений на разных форумах. а вообще код такой:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import urllib2
from xml.dom.minidom import Document
def do_request(request):
    data = request
    connection = urllib2.build_opener()
    connection.addheaders = [(('WebKey', ''),
                             ('Content-Length', len(request))
                             )]
    return connection.open("https://1234:15924", data).read()
def send_order():
    ...
    xm = doc.toxml(encoding='utf-8')
    sxml = do_request(xm)
    return sxml
Дальше строку
return connection.open("https://1234:15924", data).read()
Я разнес, как:
response = connection.open("https://1234:15924", data)
return response.read()
И валится на строке:
connection.open("https://1234:15924", data)
По-поводу документации, я читал и сейчас вернусь еще раз, возможно, что-то упустил. Но именно для этого и обращаюсь на форум.

Отредактировано volframka (Ноя. 27, 2013 09:42:53)

Офлайн

#5 Ноя. 27, 2013 09:47:09

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

urllib2 askii

А что у Вас в данном случае есть request?

data should be a buffer in the standard application/x-www-form-urlencoded format



Офлайн

#6 Ноя. 27, 2013 10:21:47

volframka
Зарегистрирован: 2013-11-26
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

urllib2 askii

FishHook Спасибо за ответ, действительно, этот момент я упустил

FishHook
А что у Вас в данном случае есть request?
Честно говоря, не совсем понимаю в какую кодировку переводить. Написано, что application/x-www-form-urlencoded - ascii. мне она не подходит. А в заголовок добавил:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals 
from xml.dom.minidom import Document
import urllib2
def do_request(request):
    data = request
    connection = urllib2.build_opener()
    connection.addheaders = [('Content-Length', len(request)),
                             ('Content-type', 'application/x-www-form-urlencoded'),
                             ('Accept-Charset', 'utf-8')]
    response = connection.open("http://1230:5541/?OperationType=1", data)
    return response.read()

Отредактировано volframka (Ноя. 27, 2013 10:22:04)

Офлайн

#7 Ноя. 27, 2013 10:48:26

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

urllib2 askii

Тут вопрос вообще в другом, например, в Джанге request - обязательный параметр каждого представления, это объект класса HttpRequest, часть фреймворка. Разумеется, если я попытаюсь передать этот request в connection.open случится какая-нибудь ошибка, просто потому, что этот реквест никаким образом не application/x-www-form-urlencoded. Точно так же слажает request из wergzeug или webob.
какой вообще тип у этого параметра?



Офлайн

#8 Ноя. 27, 2013 10:54:57

volframka
Зарегистрирован: 2013-11-26
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

urllib2 askii

FishHook
какой вообще тип у этого параметра?
        xm = doc.toxml(encoding='utf-8')
        sxml = do_request(xm)

Тип - string, кодировка - utf-8

Отредактировано volframka (Ноя. 27, 2013 10:58:11)

Офлайн

#9 Ноя. 27, 2013 12:51:33

volframka
Зарегистрирован: 2013-11-26
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

urllib2 askii

Что-то в миндоме..
Если создаю xml с помощью “etree”, то все нормально работает!

Офлайн

#10 Ноя. 27, 2013 17:05:09

bw
От:
Зарегистрирован: 2007-09-26
Сообщения: 938
Репутация: +  20  -
Профиль   Адрес электронной почты  

urllib2 askii

А если `assert type(data) is str` скажет об обратном, что будем делать?
Почему я буду говорить с вами как со школьником? Потому что только школьник может писать `data = unicode(data, ‘utf-8’)` и делать непонятное лицо, мол почему ошибка, у меня везде `str` как “я читал”.

> если и так понятно, что ошибка в кодировке?
Поясняю. Многие берут за правило, показывать один код, а тестировать другой. А traceback помогает выявить таких добрых, но неблагодарных людей. Может у вас там вообще ошибка при разборе заголовков, которые формируются вовсе не тем образом, что вы тут нам показываете.

И что это за…

  • `connection.addheaders` – почему не как все, не через `urllib2.Request`?
  • `len(request)` – ничё так, что мы `data` передаём, а не `request`?

p.s. “Content-Length” можно опускать, `urllib2` справится с этим самостоятельно, хоть на одну ошибку из-за человеческого фактора будет меньше.

p.p.s. “Content-Type”, я могу ошибаться, но в вашем случае он вероятно должен быть “application/octet-stream” (или “text/xml”). Хотя именно с этой ошибкой данный заголовок естественно никак не связан, но может на сервере придётся ловить нежданчики.

..bw



Отредактировано bw (Ноя. 27, 2013 17:17:09)

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version