2015-06-10 8 views
11

Sto provando a convertire il codice Python 2.7 funzionante in codice Python 3 e sto ricevendo un errore di tipo dal modulo di richiesta urllib.urllib di Python 3 produce TypeError: i dati POST devono essere byte o un iterabile di byte. Non può essere di tipo str

utilizzato lo strumento 2to3 Python integrato per convertire l'urllib sotto di lavoro e urllib2 codice Python 2.7:

import urllib2 
import urllib 

url = "https://www.customdomain.com" 
d = dict(parameter1="value1", parameter2="value2") 

req = urllib2.Request(url, data=urllib.urlencode(d)) 
f = urllib2.urlopen(req) 
resp = f.read() 

L'uscita dal modulo 2to3 era il sotto Python 3 codice:

import urllib.request, urllib.error, urllib.parse 

url = "https://www.customdomain.com" 
d = dict(parameter1="value1", parameter2="value2") 

req = urllib.request.Request(url, data=urllib.parse.urlencode(d)) 
f = urllib.request.urlopen(req) 
resp = f.read() 

Quando viene eseguito il codice Python 3 viene generato il seguente errore:

--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-56-206954140899> in <module>() 
     5 
     6 req = urllib.request.Request(url, data=urllib.parse.urlencode(d)) 
----> 7 f = urllib.request.urlopen(req) 
     8 resp = f.read() 

C:\Users\Admin\Anaconda3\lib\urllib\request.py in urlopen(url, data, timeout, cafile, capath, cadefault, context) 
    159  else: 
    160   opener = _opener 
--> 161  return opener.open(url, data, timeout) 
    162 
    163 def install_opener(opener): 

C:\Users\Admin\Anaconda3\lib\urllib\request.py in open(self, fullurl, data, timeout) 
    459   for processor in self.process_request.get(protocol, []): 
    460    meth = getattr(processor, meth_name) 
--> 461    req = meth(req) 
    462 
    463   response = self._open(req, data) 

C:\Users\Admin\Anaconda3\lib\urllib\request.py in do_request_(self, request) 
    1110     msg = "POST data should be bytes or an iterable of bytes. " \ 
    1111      "It cannot be of type str." 
-> 1112     raise TypeError(msg) 
    1113    if not request.has_header('Content-type'): 
    1114     request.add_unredirected_header(

TypeError: POST data should be bytes or an iterable of bytes. It cannot be of type str. 

I ha Ho anche letto altri due biglietti (ticket1 e) che citavano la codifica della data.

Quando ho cambiato la linea f = urllib.request.urlopen(req)-f = urllib.request.urlopen(req.encode('utf-8')) ho ricevuto il seguente errore: AttributeError: 'Request' object has no attribute 'encode'

Sono bloccato su come far funzionare il codice Python 3. Per favore potete aiutarmi?

risposta

22

Dal docsnoti che params uscita dal urlencode è codificato per byte prima di essere inviato a urlopen come dati:

data = urllib.parse.urlencode(d).encode("utf-8") 
req = urllib.request.Request(url) 
with urllib.request.urlopen(req,data=data) as f: 
    resp = f.read() 
    print(resp) 
+3

L'aggiunta di 'encode (" utf-8 ")' ha funzionato per me. Grazie. –

1

Prova questo:

url = 'https://www.customdomain.com' 
d = dict(parameter1="value1", parameter2="value2") 

f = urllib.parse.urlencode(d) 
f = f.encode('utf-8') 

req = urllib.request.Request(url, f) 

Il tuo problema risiede nella modo in cui gestivi il dizionario.

+0

Anche questo metodo funziona. Grazie – Greg

Problemi correlati