2015-06-10 30 views
11

Próbuję przekonwertować działający kod w języku Python 2.7 do kodu Python 3 i otrzymuję błąd typu z modułu żądania urllib.Python 3 urllib tworzy TypeError: dane POST powinny być bajtami lub liczbą bajtów. Nie może być typu str

I używana wbudowane narzędzia 2to3 Pythona konwersji urllib poniżej pracy i urllib2 Pythonie 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() 

Dane wyjściowe z modułu 2to3 była poniżej Pythona kodu 3:

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() 

Po uruchomieniu kodu Python 3 generowany jest następujący błąd:

--------------------------------------------------------------------------- 
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. 

Ja ha Przeczytałem również dwa inne bilety (ticket1 i ticket2), które wspomniały o kodowaniu daty.

Kiedy zmienił linię f = urllib.request.urlopen(req) do f = urllib.request.urlopen(req.encode('utf-8')) otrzymałem następujący błąd: AttributeError: 'Request' object has no attribute 'encode'

siedzę, jak zrobić pracę kodu Pythona 3. Czy mógłbyś mi pomóc?

Odpowiedz

22

Z docsZauważ, że params wyjście z urlencode jest kodowany do bajtów przed wysłaniem go do urlopen danych:

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

Dodanie 'encode (" utf-8 ")' zadziałało dla mnie. Dzięki. –

1

Spróbuj tego:

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) 

Twój problem polega na sposób obsługi słownika.

+0

Ta metoda działa również. Dzięki – Greg