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

Python urllib TypeError: POST data should be bytes or an iterable of bytes. It cannot be of type str is an error which occurs when you handle the dictionary the wrong way in python.

Today, I will explain why this error takes place and how to fix it, while also presenting the steps in detail and adding other solutions that could solve the error.

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

This is an error which occurs when you handle the dictionary the wrong way in python.

Please double check the error message bellow so you can avoid mixing between different errors.

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

In the sections bellow we will explain the source of the problem and propose many possible fixes.

The Method that solved my issue : Encode the output from urlencode to bytes before you send it to urlopen

When you handle the dictionary in python, you should know how to do it or you will end up with an error similar to the one we have.

The fix is to encode the output from urlencode to bytes before you send it to urlopen.

So, you should replace this line of code

                                                                       #
req = urllib.request.Request(url, data=urllib.parse.urlencode(d))
                                                                       #

With the following line

                                                                       #
req = urllib.request.Request(url)
                                                                       #

This means, if your code looks like this

                                                                       #
req = urllib.request.Request(url, data=urllib.parse.urlencode(d))

f = urllib.request.urlopen(req)
resp = f.read()
                                                                       #

You should change it so that the output from urlencode is encoded to bytes before you send it to urlopen.

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

Another option is instead of doing

                                                                       #
f = urllib2.urlopen(req)
                                                                       #

You can use .urlencode(d) before encoding to utf-8

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

and finally use urllib.request.Request with parameters url and f

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

Thank you guys for reaching the end of this bog post, I hope I helped you solve this problem or at least guided you in the right direction.

Summing-up : 

That is it guys, this is the end of this article/guide, I hope you found it useful in solving the error : Fixing Python urllib TypeError POST data should be bytes or an iterable of bytes. It cannot be of type str .

You can support our work on our Kofi account.

Thank you for reading my blog post to the end, If you want to learn more about the Python programming language, check out the official Python Documentation : https://docs.python.org/3/