Python - 不使用第三方 library,怎么发送 post multipart/form-data HTTP 请求?

2022-12-15 17:38:36 +08:00
 JasonLaw

Python 版本为 3.5 ,在不使用类似Requests等第三方 library 的情况下,怎么发送 post multipart/form-data HTTP 请求(会有文件上传)?

可以的话,麻烦给出完整的代码示例,谢谢。

我找了好久,使用 urllib 来发送,但是都不成功。我找到的资料有:

2469 次点击
所在节点    Python
9 条回复
learningman
2022-12-15 20:34:39 +08:00
你的第二个不就是吗,binascii 是内置库
ClericPy
2022-12-15 21:01:30 +08:00
data = urlencode(form, doseq=True).encode("utf-8")
headers.setdefault("Content-Type", "application/x-www-form-urlencoded")

最近正在写 built-ins 补充工具, 还没开源, 你先试试吧
ClericPy
2022-12-15 21:01:58 +08:00
发错了... 忽略我, 没看清楚头...
haha512
2022-12-15 23:16:40 +08:00
```
import urllib.request
import urllib.parse

with open('myfile.txt', 'rb') as f:
file_data = f.read()


# 编码表单数据
form_data = urllib.parse.urlencode({
'file': file_data,
'field1': 'value1',
'field2': 'value2'
}).encode('utf-8')


# 发送请求
req = urllib.request.Request('http://httpbin.org/post', data=form_data, headers={
'Content-Type': 'multipart/form-data'
})
res = urllib.request.urlopen(req)

# 读取响应
print(res.read().decode('utf-8'))


```
JasonLaw
2022-12-16 09:27:50 +08:00
@haha512 #4 你这应该是 chatGPT 的,对吗?是的话,建议还是标明一下来源。

我自己在提问之前已经试过 chatGPT 提供的答案了,都不行,包括你的这个,你自己试过了吗?可以吗?
ruanimal
2022-12-16 10:42:58 +08:00
@JasonLaw chatGPT 的答案还带注释的?
haha512
2022-12-16 10:57:45 +08:00
这个实测可以

`
import mimetypes, http.client
import json



boundary = 'wL36Yn8afVp8Ag7AmP8qZ0SA4n1v9T' # Randomly generated
fileName='./1.txt'
dataList=[]
# Add boundary and header
dataList.append('--' + boundary)
dataList.append('Content-Disposition: form-data; name={0}; filename={0}'.format(fileName))
fileType = mimetypes.guess_type(fileName)[0] or 'application/octet-stream'
dataList.append('Content-Type: {}'.format(fileType))
dataList.append('')

with open(fileName) as f:
dataList.append(f.read())

dataList.append('--'+boundary+'--')
dataList.append('')
contentType = 'multipart/form-data; boundary={}'.format(boundary)

body = '\r\n'.join(dataList)
headers = {'Content-type': contentType}

conn = http.client.HTTPConnection('httpbin.org:80')
req = conn.request('POST', '/post', body, headers)

print(str(conn.getresponse().read().decode('utf-8')))

`


返回响应
`
{
"args": {},
"data": "",
"files": {
"./1.txt": "asdgsadga"
},
"form": {},
"headers": {
"Accept-Encoding": "identity",
"Content-Length": "173",
"Content-Type": "multipart/form-data; boundary=wL36Yn8afVp8Ag7AmP8qZ0SA4n1v9T",
"Host": "httpbin.org",
"X-Amzn-Trace-Id": "Root=1-639bde59-2e7b61940f7df7794549546b"
},
"json": null,
"origin": "123.234.99.81",
"url": "http://httpbin.org/post"
}

`
JasonLaw
2022-12-16 11:05:25 +08:00
@ruanimal #6 对,你可以去试试
JasonLaw
2022-12-18 20:24:05 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/902770

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX