使用Python请求中的POST表单数据上载Image

mic*_*al 21 python curl python-3.x python-requests wechat

我正在使用微信API ...在这里我要使用这个API将图像上传到微信的服务器 http://admin.wechat.com/wiki/index.php?title=Transferring_Multimedia_Files

    url = 'http://file.api.wechat.com/cgi-bin/media/upload?access_token=%s&type=image'%access_token
    files = {
        'file': (filename, open(filepath, 'rb'),
        'Content-Type': 'image/jpeg',
        'Content-Length': l
    }
    r = requests.post(url, files=files)
Run Code Online (Sandbox Code Playgroud)

我无法发布数据

kev*_*kev 41

来自wechat api doc:

curl -F media=@test.jpg "http://file.api.wechat.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE"
Run Code Online (Sandbox Code Playgroud)

将上面的命令翻译为python:

import requests
url = 'http://file.api.wechat.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE'
files = {'media': open('test.jpg', 'rb')}
requests.post(url, files=files)
Run Code Online (Sandbox Code Playgroud)

  • 如果有人需要以“文件对象”的形式提供数据,例如,如果您获得一些像“some_image = requests.get(url_to_some_image)”这样的图像,并希望将此图像发布到某个地方,则需要将图像制作为“文件”对象`。为了做到这一点,根据 Kev 的答案,您需要制作 `files = {'media': io.BytesIO(some_image.content)}` (2认同)

Rac*_*yal 15

如果您要将图像作为 JSON 的一部分与其他属性一起传递,则可以使用以下代码段。
客户端.py

import base64
import json                    

import requests

api = 'http://localhost:8080/test'
image_file = 'sample_image.png'

with open(image_file, "rb") as f:
    im_bytes = f.read()        
im_b64 = base64.b64encode(im_bytes).decode("utf8")

headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
  
payload = json.dumps({"image": im_b64, "other_key": "value"})
response = requests.post(api, data=payload, headers=headers)
try:
    data = response.json()     
    print(data)                
except requests.exceptions.RequestException:
    print(response.text)
Run Code Online (Sandbox Code Playgroud)

服务器.py

import io
import json                    
import base64                  
import logging             
import numpy as np
from PIL import Image

from flask import Flask, request, jsonify, abort

app = Flask(__name__)          
app.logger.setLevel(logging.DEBUG)
  
  
@app.route("/test", methods=['POST'])
def test_method():         
    # print(request.json)      
    if not request.json or 'image' not in request.json: 
        abort(400)
             
    # get the base64 encoded string
    im_b64 = request.json['image']

    # convert it into bytes  
    img_bytes = base64.b64decode(im_b64.encode('utf-8'))

    # convert bytes data to PIL Image object
    img = Image.open(io.BytesIO(img_bytes))

    # PIL image object to numpy array
    img_arr = np.asarray(img)      
    print('img shape', img_arr.shape)

    # process your img_arr here    
    
    # access other keys of json
    # print(request.json['other_key'])

    result_dict = {'output': 'output_key'}
    return result_dict
  
  
def run_server_api():
    app.run(host='0.0.0.0', port=8080)
  
  
if __name__ == "__main__":     
    run_server_api()
Run Code Online (Sandbox Code Playgroud)


小智 8

当我想将图像文件从 Python 发布到 rest API(虽然不是微信 API)时,我遇到了类似的问题。我的解决方案是使用“数据”参数以二进制数据而不是“文件”形式发布文件。 请求 API 参考

data = open('your_image.png','rb').read()
r = requests.post(your_url,data=data)
Run Code Online (Sandbox Code Playgroud)

希望这适用于您的情况。


Ale*_*oya 6

使用这个片段

import os
import requests
url = 'http://host:port/endpoint'
with open(path_img, 'rb') as img:
  name_img= os.path.basename(path_img)
  files= {'image': (name_img,img,'multipart/form-data',{'Expires': '0'}) }
  with requests.Session() as s:
    r = s.post(url,files=files)
    print(r.status_code)
Run Code Online (Sandbox Code Playgroud)

  • Expires 扮演什么角色? (3认同)

Pav*_*eev 5

import requests

image_file_descriptor = open('test.jpg', 'rb')
# Requests makes it simple to upload Multipart-encoded files 
files = {'media': image_file_descriptor}
url = '...'
requests.post(url, files=files)
image_file_descriptor.close()
Run Code Online (Sandbox Code Playgroud)

不要忘记关闭描述符,它可以防止错误:明确关闭文件重要吗?

  • 使用`with open('test.jpg', 'rb') 作为图像文件描述符:`。 (3认同)