美文网首页生活不易 我用python
Python上传磁盘和网络图片,使用requests

Python上传磁盘和网络图片,使用requests

作者: 一杯半盏 | 来源:发表于2017-05-16 16:24 被阅读2321次

    从磁盘上传:

    复习基本代码:

    open(path, 'rb') #打开文件
    os.path.basename(path) #获取文件名
    requests.post(url, data, json, **kwargs) #requests请求
    

    上传代码:

    import requests
    
    
    data_param= {"some_key": "yibeibanzhan", "timestamp": 1494920537,
    'img_name': image_name}
    file_obj = open(path, 'rb')
    img_file= {image_name: file_obj}#fixed at 2017-05-19 10:49:57
    
    data_result = requests.post(url, data_param, files=img_file)
    if isinstance(file_obj, file):
        file_obj.close()      
    

    上传图片的同时可以附带一些参数在data_param中,API调用的时候一般要传一些例如api_key的东西。如果需要获取文件名,上面列出了获得本地文件的文件名的技巧。
    从本地上传图片的话,open得到file对象,那么 files=img_file 中的key无所谓叫什么名字,都上传能够成功,原理在后面解释

    从URL获取图片并直接上传

    import urllib2
    import cStringIO
    from PIL import Image
    import io
    
    def load_image(url):
        image_file = cStringIO.StringIO(urllib2.urlopen(url).read())
        image_data = Image.open(image_file)
        output = io.BytesIO()
        image_data.save(output, format='JPEG') # format=image_data.format
        print image_data.format #输出的不一定是JPEG也可能是PNG
        image_data.close()
        data_bin = output.getvalue()
        output.close()
        return data_bin
    

    那么同样,可以重用之前的代码:

    image_name = 'xxx'
    data_param= {"some_key":"yibeibanzhan", "timestamp":1494920537,
    'img_name': image_name} #有些API要求指定文件名参数
    file_obj = load_image(url)
    #fixed at 2017-05-19 10:49:57
    img_file= {image_name: file_obj} #Very Important. 
    #the key must be the filename, 
    #because the requests cannot guess the correct filename from the bytes array.
    data_result = requests.post(url, data_param, files=img_file)
    if isinstance(file_obj, file): #这里load_image获得的是二进制流了,不是file对象。
        file_obj.close()      
    

    更新2017-05-19 10:59:52

    关于上传的files参数的改正:

    requests的\requests\models.py中 145行左右:

    def _encode_files(files, data):
        ...
                    else:
                    fn = guess_filename(v) or k
                    fp = v
        ...
        rf = RequestField(name=k, data=fdata, filename=fn, headers=fh)
    
    

    这里会根据传入的

    img_file= {image_name: file_obj}
    

    猜测他的文件名:当他是file对象的时候,可以通过file.name获得最终正确的文件名,当他是字节流,byte array的时候,只能通过image_name这个字符串获得。

    因此,为了避免出现上传文件的文件名不一致,导致API提供方校验不通过的问题,这里必须提供文件名。

    以上。

    industrial code for production

    相关文章

      网友评论

        本文标题:Python上传磁盘和网络图片,使用requests

        本文链接:https://www.haomeiwen.com/subject/hgmlxxtx.html