Ошибка Python 3.0 urllib.parse "Тип str не поддерживает API-интерфейс буфера"
File "/usr/local/lib/python3.0/cgi.py", line 477, in __init__
self.read_urlencoded()
File "/usr/local/lib/python3.0/cgi.py", line 577, in read_urlencoded
self.strict_parsing):
File "/usr/local/lib/python3.0/urllib/parse.py", line 377, in parse_qsl
pairs = [s2 for s1 in qs.split('&') for s2 in s1.split(';')]
TypeError: Type str doesn't support the buffer API
Может ли кто-нибудь направить меня на то, как этого избежать? Я получаю это через подачу данных в cgi.Fieldstorage
, и я не могу сделать это иначе.
Ответы
Ответ 1
urllib пытается:
b'a,b'.split(',')
Что не работает. байтовые строки и строки Юникода смешиваются еще менее плавно в Py3k, чем раньше - преднамеренно, чтобы проблемы с кодированием не совпали раньше, чем позже.
Таким образом, ошибка довольно непрозрачно говорит вам: "Вы не можете передать байтовую строку в urllib.parse. Предположительно, вы делаете запрос POST, где строка, закодированная в форме, входит в cgi как тело контента; тело содержимого по-прежнему является байтовой строкой/потоком, поэтому теперь оно сталкивается с новым urllib.
Итак, это ошибка в cgi.py, еще одна жертва преобразования 2to3, которая не была исправлена должным образом для новой строковой модели. Он должен преобразовывать входящий поток байтов в символы перед передачей их в urllib.
Я упоминал библиотеки Python 3.0 (особенно связанные с веб-сайтами), которые все еще были довольно шонки?: -)
Ответ 2
Из учебника python (http://www.python.org/doc/3.0/tutorial/stdlib.html) приведен пример использования метода urlopen. Он вызывает ту же ошибку.
for line in urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'):
if 'EST' in line or 'EDT' in line: # look for Eastern Time
print(line)
Вам понадобится использовать функцию str для преобразования байта thingo в строку с правильной кодировкой. Как показано ниже:
for line in urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'):
lineStr = str( line, encoding='utf8' )
if 'EST' in lineStr or 'EDT' in lineStr: # look for Eastern Time
print(lineStr)