开发者

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

I just updated from python 3.1 to python 3.2 (formatted HD) and one of my scripts stopped working. It gives me the error in the title.

I would fix it myself but I don't even know what an iterable of bytes is lol. I tried typecasting bytes(data) but that开发者_StackOverflow社区 didn't work either. TypeError: string argument without an encoding

url = "http://example.com/index.php?app=core&module=global&section=login&do=process"
values = {"username" : USERNAME, 
          "password" : PASSWORD}
data = urllib.parse.urlencode(values)
req = urllib.request.Request(url, data)
urllib.request.urlopen(req)

It crashes at the last line.

Works in 3.1, but not 3.2


You did basically correct in trying to convert the string into bytes, but you did it the wrong way. Python doesn't have typecasting (so what you did was not typecasting).

The way to do it is to encode the text data into bytes data, which you do with the encode function:

binary_data = data.encode('encoding')

What 'encoding' should be depends. You should probably use 'ascii' here. If you have characters that aren't ASCII, then you need to use another encoding, typically 'utf8', but then you also need to tell the receiving webserver that it is UTF-8. It might also not want UTF8, but then you have to ask it, and it's getting complicated. :-)


@Enders, I know this is an old question, but I'd like to explain a few more things for somebody fighting with this issue.

It is specifically with this line of code here:

data = urllib.parse.urlencode(values)

That you are having issues, as you are trying to encode the data: values (urlencode).

If you refer to the urllib.parse documentation scroll to the bottom to find what urlencode does: https://docs.python.org/3/library/urllib.parse.html <~ you will see that you are trying to encode your user/pass into a data string:

Convert a mapping object or a sequence of two-element tuples, which may contain str or bytes objects, to a percent-encoded ASCII text string. If the resultant string is to be used as a data for POST operation with the urlopen() function, then it should be encoded to bytes, otherwise it would result in a TypeError.

Perhaps what you are trying to do here is do some kind of encryption of your user/password, but I don't really think this is the right way. If it is, then you probably need to make sure that the receiving end (the destination of your url) know that you're encoding your user/pass with this.

A more up-to-date approach is to use the powerful Requests library. They have compatibility with very common authentication protocols: http://docs.python-requests.org/en/master/user/authentication/

In this case, I'd do something like this:

requests.get(url, auth=('user', 'pass'))
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜