V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
JasonLaw
V2EX  ›  Python

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

  •  
  •   JasonLaw · 2022-12-15 17:38:36 +08:00 · 2600 次点击
    这是一个创建于 707 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    第 1 条附言  ·  2022-12-16 09:30:41 +08:00

    最后我使用了一个workaround来解决,Python直接调用curl,参考Execute curl command within a Python script - Stack Overflow 的一个答案

    第 2 条附言  ·  2022-12-18 20:22:52 +08:00

    其实Python - HTTP multipart/form-data POST request - Stack Overflow这个问题已经给出了答案了,之前是我搞错了,觉得这种方法不行。

    9 条回复    2022-12-18 20:24:05 +08:00
    learningman
        1
    learningman  
       2022-12-15 20:34:39 +08:00
    你的第二个不就是吗,binascii 是内置库
    ClericPy
        2
    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
        3
    ClericPy  
       2022-12-15 21:01:58 +08:00
    发错了... 忽略我, 没看清楚头...
    haha512
        4
    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
        5
    JasonLaw  
    OP
       2022-12-16 09:27:50 +08:00
    @haha512 #4 你这应该是 chatGPT 的,对吗?是的话,建议还是标明一下来源。

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

    `
    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
        8
    JasonLaw  
    OP
       2022-12-16 11:05:25 +08:00 via iPhone
    @ruanimal #6 对,你可以去试试
    JasonLaw
        9
    JasonLaw  
    OP
       2022-12-18 20:24:05 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5417 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 06:47 · PVG 14:47 · LAX 22:47 · JFK 01:47
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.