Ошибка Python 3.0 urllib.parse «Тип str не поддерживает API буфера»
-
22-08-2019 - |
Вопрос
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
и я не могу сделать это по-другому.
Решение
urllib пытается сделать:
b'a,b'.split(',')
Это не работает.байтовые строки и строки Юникода смешиваются в Py3k еще менее плавно, чем раньше — намеренно, чтобы проблемы с кодированием пошли не так раньше, чем позже.
Таким образом, ошибка довольно неясно говорит вам: «Вы не можете передать байтовую строку в urllib.parse».Предположительно, вы выполняете запрос POST, где строка, закодированная в форме, поступает в cgi как тело содержимого;тело содержимого по-прежнему представляет собой байтовую строку/поток, поэтому теперь оно конфликтует с новой urllib.
Так что да, это ошибка в cgi.py, еще одна жертва преобразования 2 в 3, которая не была исправлена должным образом для новой строковой модели.Он должен преобразовать входящий поток байтов в символы перед передачей их в urllib.
Я уже упоминал, что библиотеки Python 3.0 (особенно связанные с Интернетом) все еще довольно ненадежны?:-)
Другие советы
Из руководства по 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 для преобразования байтовой вещи в строку с правильной кодировкой.Следующее:
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)