Python 3.0 urllib.parse erro “Tipo str não suporta a API tampão”
-
22-08-2019 - |
Pergunta
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
Alguém pode dirigir-me sobre como evitar isso? Estou ficando-lo através de dados que alimentam o cgi.Fieldstorage
e eu não consigo fazê-lo de outra maneira.
Solução
urllib está tentando fazer:
b'a,b'.split(',')
O que não funciona. strings de bytes e strings unicode misturam ainda menos sem problemas em Py3k do que costumavam -. deliberadamente, para fazer a codificação dos problemas errado, mais cedo ou mais tarde
Então, o erro é bastante opaquely dizendo ‘você não pode passar uma seqüência de byte para urllib.parse’. Provavelmente, você está fazendo uma solicitação POST, onde a string codificada em forma está entrando em cgi como um corpo de conteúdo; o corpo conteúdo ainda é uma seqüência de byte / fluxo de modo que agora se choca com o novo urllib.
Então, sim, é um bug no cgi.py, mais uma vítima da conversão 2to3 que não foi fixado corretamente para o novo modelo string. Deve ser converter o fluxo de bytes de entrada para caracteres antes de passá-los para urllib.
Eu mencionei bibliotecas Python 3.0 do (especialmente web-relacionadas) ainda sendo bastante shonky? : -)
Outras dicas
A partir do tutorial python ( http://www.python.org/doc /3.0/tutorial/stdlib.html ) não é um exemplo da utilização método urlopen. Ela levanta o mesmo erro.
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)
Você vai precisar usar a função str para converter o byte thingo para uma string com a codificação correta. Da seguinte forma:
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)