2015-06-10 31 views
11

我想將工作的Python 2.7代碼轉換成Python 3代碼,並且我從urllib請求模塊接收到一個類型錯誤。Python 3 urllib產生TypeError:POST數據應該是字節或可迭代的字節。它不能是類型str

我使用了內置2to3的Python的工具,以下面的工作的urllib和的urllib2的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() 

從2to3的模塊的輸出是下面的Python 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() 

當運行Python 3代碼時,會產生以下錯誤:

--------------------------------------------------------------------------- 
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我還讀了其他兩張門票(ticket1ticket2),其中提到了編碼日期。

當我改了行f = urllib.request.urlopen(req)f = urllib.request.urlopen(req.encode('utf-8'))我收到以下錯誤:AttributeError: 'Request' object has no attribute 'encode'

我堅持就如何使Python的3碼的工作。你可以幫我嗎?

回答

22

docs注意PARAMS發送到的urlopen數據之前,從進行urlencode輸出編碼爲字節:

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

添加'encode(「utf-8」)'爲我工作。謝謝。 –

1

試試這個:

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) 

你的問題就出在你處理字典的方式。

+0

這種方法也適用。謝謝 – Greg

相關問題