2015-06-10 22 views
11

Tôi đang cố gắng chuyển đổi mã Python 2.7 hoạt động thành mã Python 3 và tôi nhận được một lỗi kiểu từ mô-đun yêu cầu urllib.Python 3 urllib tạo ra TypeError: Dữ liệu POST phải là byte hoặc một byte có thể lặp lại. Nó không thể có kiểu str

tôi sử dụng công cụ 2to3 Python sẵn để chuyển đổi urllib dưới đây làm việc và urllib2 mã 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() 

Kết quả từ các mô-đun 2to3 là ​​dưới Python 3 mã:

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

Khi mã Python 3 được chạy, lỗi sau được tạo ra:

--------------------------------------------------------------------------- 
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 cũng đã đọc hai vé khác (ticket1ticket2) đã đề cập đến mã hóa ngày tháng.

Khi tôi thay đổi dòng f = urllib.request.urlopen(req)-f = urllib.request.urlopen(req.encode('utf-8')) tôi nhận được lỗi sau: AttributeError: 'Request' object has no attribute 'encode'

Tôi đang mắc kẹt như thế nào để làm cho công việc mã Python 3. Liệu bạn có thể giúp mình không?

Trả lời

22

Từ docsLưu ý rằng params đầu ra từ urlencode được mã hóa để byte trước khi nó được gửi tới urlopen như dữ liệu:

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

Thêm 'mã hóa (" utf-8 ")' đã hoạt động cho tôi. Cảm ơn. –

1

Hãy thử điều này:

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) 

Vấn đề của bạn nằm trong cách bạn đang xử lý từ điển.

+0

Phương pháp này cũng hoạt động. Cảm ơn – Greg

Các vấn đề liên quan