Python3通过HTTP POST发送图片报错expected str instance, bytes found如何解决
问题原因
- Python3对
str(Unicode字符串)和bytes(二进制字节串)做了严格的类型区分,不允许两种类型直接拼接 - 你的代码中列表
L同时包含了字符串类型的HTTP头字段、和二进制类型的图片内容image,用字符串类型的CRLF执行join操作时就会触发类型不匹配报错 - 你之前尝试的
str(image)会直接把字节对象的表示(带b''标识)转为字符串,image.decode()会把二进制图片当做UTF-8文本解码,两种操作都会破坏原始图片数据,因此不可用
修复方案
统一把所有参与拼接的内容转为bytes类型后再拼接,修改后的代码如下:
import http.client BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$' # CRLF改为字节类型 CRLF = b'\r\n' L = [] # 所有字符串类型的头部字段统一编码为utf-8字节 L.append(('--' + BOUNDARY).encode('utf-8')) L.append(('Content-Disposition: form-data; name="s"; filename="%s"' % (file_name)).encode('utf-8')) L.append(('Content-Type: %s' % mime_type).encode('utf-8')) # 空行也要编码为字节 L.append(b'') # image本身已经是rb读取的字节,无需修改 L.append(image) L.append(('--' + BOUNDARY + '--').encode('utf-8')) L.append(b'') # 用字节类型的CRLF拼接,得到的body是字节类型 body = CRLF.join(L) http1 = http.client.HTTPSConnection(REMOTE_HOST) http1.connect() http1.putrequest("POST", UPLOAD_URL) # 头部字段传字符串即可,http.client会自动处理编码 http1.putheader('Content-type', 'multipart/form-data; boundary=%s' % BOUNDARY) # 此时len(body)是正确的字节长度 http1.putheader('Content-length', str(len(body))) http1.endheaders() # send方法可以直接接收字节类型的body http1.send(body) r = http1.getresponse()
额外说明
如果不想手动拼接multipart表单,也可以用第三方HTTP库的文件上传接口实现需求,代码会更简洁不易出错
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

