curl转Python urllib.request实现图片上传报500错误求解
问题原因
- 你使用的
parse.urlencode()生成的是application/x-www-form-urlencoded格式的请求体,仅支持传递普通文本键值对;而curl的--form参数使用的是multipart/form-data格式,专门用于提交包含二进制文件的表单,两种编码格式完全不兼容,服务器无法解析你提交的内容。 - 直接把二进制文件对象传入
urlencode时,只会被转成文件对象的字符串表示,不会实际读取上传文件的二进制内容,服务器收到的根本不是有效的图片数据。
修复代码
urllib没有内置的multipart表单构造能力,需要手动拼接符合规范的请求体,可用以下代码实现和原curl完全等价的效果:
import json import uuid from urllib import request # 生成随机边界,避免和文件内容冲突 boundary = uuid.uuid4().hex # 构造multipart格式请求体 body = [] # 添加图片表单字段 body.append(f'--{boundary}') body.append('Content-Disposition: form-data; name="image"; filename="file.jpg"') body.append('Content-Type: image/jpeg') body.append('') # 读取图片二进制内容 with open("path/to/dir/file.jpg", "rb") as f: body.append(f.read()) # 添加请求体结束标记 body.append(f'--{boundary}--') # 统一编码拼接 body = [part.encode('utf-8') if isinstance(part, str) else part for part in body] body = b'\r\n'.join(body) # 构造请求 req = request.Request("http://api.textart.io/img2txt.json", method='POST') # 必须设置正确的Content-Type头携带边界信息 req.add_header('Content-Type', f'multipart/form-data; boundary={boundary}') req.add_header('Content-Length', str(len(body))) req.add_header('User-Agent', 'Mozilla/5.0') # 发起请求并打印结果 response = json.loads(request.urlopen(req, data=body).read()) print(json.dumps(response, indent=4))
内容的提问来源于stack exchange,提问作者user16767252
相关产品推荐
相关产品推荐

