python MultipartEncoder传输zip文件实例


Posted in Python onApril 07, 2020

需求:对方提供处理文件的接口,本地将待处理文件压缩后,通过http post multipart方式上传,等待处理完成后从相应连接下载结果

代码:

import os
import time
import zipfile
import requests
from requests_toolbelt.multipart.encoder import MultipartEncoder
 
 
class Func4Fuxi(object):
 
  def __init__(self):
    self.remote_result = 0
  
  # 压缩文件 
  def zip_dir(self, dirname, zipfilename):
    filelist = []
    if os.path.isfile(dirname):
      filelist.append(dirname)
    else:
      for root, dirs, files in os.walk(dirname):
        for name in files:
          filelist.append(os.path.join(root, name))
      zf = zipfile.ZipFile(zipfilename, mode="w", compression=zipfile.zlib.DEFLATED, allowZip64=True)
      for tar in filelist:
        arcname = tar[len(dirname):]
        zf.write(tar, arcname)
      zf.close()
  
  # 解压文件 
  def unzip_file(self, zipfilename, unziptodir):
    if not os.path.exists(unziptodir):
      os.mkdir(unziptodir)
    zfobj = zipfile.ZipFile(zipfilename)
    for name in zfobj.namelist():
      name = name.replace('\\', '/')
      if name.endswith('/'):
        os.mkdir(os.path.join(unziptodir, name))
      else:
        ext_filename = os.path.join(unziptodir, name)
        ext_dir = os.path.dirname(ext_filename)
        if not os.path.exists(ext_dir):
          os.mkdir(ext_dir)
        outfile = open(ext_filename, 'wb')
        outfile.write(zfobj.read(name))
        outfile.close()
  
  # 下载
  def download_result(self, filename):
    filename.replace('\\', '/')
    file = filename.split('/')[-1]
    URL = '--------------'
    re = requests.get(URL+'?name='+file, stream=True)
    self.remote_result = re.status_code
    if self.remote_result == 200:
      print("find result,try to download")
      f = open("download_"+file, "wb")
      for chunk in re.iter_content(chunk_size=512):
        if chunk:
          f.write(chunk)
      print("download result success")
    return self.remote_result
  
  # 上传
  def upload_zip(self, filename):
    self.remote_result = 0
    filename.replace('\\', '/')
    file = filename.split('/')[-1]
    file_tup = (file, open(filename, 'rb'), 'application/zip')
    URL = '-----------------'
    #fields属性根据对方接口说明设置
    m = MultipartEncoder(
      fields={'name': file, 'zipfile': file_tup}
    )
    
    re = requests.post(URL, data=m, headers={'Content-Type': m.content_type})
    self.remote_result = re.status_code
    if self.remote_result == 200:
      print("upload success")
    else:
      print("upload failed")
    return self.remote_result

补充知识:Python模拟浏览器上传文件脚本(Multipart/form-data格式)

http协议本身的原始方法不支持multipart/form-data请求,这个请求由原始方法演变而来的。

multipart/form-data的基础方法是post,也就是说是由post方法来组合实现的,与post方法的不同之处:请求头,请求体。

multipart/form-data的请求头必须包含一个特殊的头信息:

Content-Type,且其值也必须规定为multipart/form-data,同时还需要规定一个内容分割符用于分割请求体中的多个post的内容,如文件内容和文本内容自然需要分割开来,不然接收方就无法正常解析和还原这个文件了。

具体的头信息如下:

Content-Type: multipart/form-data; boundary=${bound}

实例:

import os, random, sys, requests
from requests_toolbelt.multipart.encoder import MultipartEncoder
 
url = 'http://127.0.0.1/sendmsg'
argvstr = sys.argv[1:]
argv_dict = {}
for argv in argvstr :
  argv = str(argv).replace("\r\n" , "")
  DICT = eval(argv)
  argv_dict.update(DICT)
 
headers = {
  'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:50.0) Gecko/20100101 Firefox/50.0',
  'Referer': url
  }
 
multipart_encoder = MultipartEncoder(
  fields={
    'username': argv_dict['username'],
    'pwd': argv_dict['pwd'],
    'type': 'txt',
    'friendfield': argv_dict['friendfield'],
    'friend': argv_dict['friend'],
    'content': argv_dict['content'],
    'file': (os.path.basename(argv_dict['file']) , open(argv_dict['file'], 'rb'), 'application/octet-stream')
    #file为路径
    },
    boundary='-----------------------------' + str(random.randint(1e28, 1e29 - 1))
  )
 
headers['Content-Type'] = multipart_encoder.content_type
#请求头必须包含一个特殊的头信息,类似于Content-Type: multipart/form-data; boundary=${bound}
 
r = requests.post(url, data=multipart_encoder, headers=headers)
print(r.text)
#注意,不要设置cookies等其他参数,否则会报错
 
# 例子/usr/local/python36/bin/python3 /opt/lykchat/test_upload.py "{'username':'lykchat','pwd':'123456','type':'img','friendfield':'1','friend':'xxxx','content':'恭喜发财','file':'/root/b.jpg'}"
#等同于curl -F "file=@/root/a" 'http://127.0.0.1/sendmsg?username=lykchat&pwd=123456&type=img&friendfield=1&friend=xxxx&content=恭喜发财'

以上这篇python MultipartEncoder传输zip文件实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python解析xml文件实例分析
May 27 Python
使用Python的Flask框架表单插件Flask-WTF实现Web登录验证
Jul 12 Python
[原创]pip和pygal的安装实例教程
Dec 07 Python
python使用Plotly绘图工具绘制水平条形图
Mar 25 Python
使用python os模块复制文件到指定文件夹的方法
Aug 22 Python
python numpy之np.random的随机数函数使用介绍
Oct 06 Python
python 发送json数据操作实例分析
Oct 15 Python
在OpenCV里使用特征匹配和单映射变换的代码详解
Oct 23 Python
Python响应对象text属性乱码解决方案
Mar 31 Python
基于python实现matlab filter函数过程详解
Jun 08 Python
区分python中的进程与线程
Aug 13 Python
Python中npy和mat文件的保存与读取
Apr 24 Python
xadmin使用formfield_for_dbfield函数过滤下拉表单实例
Apr 07 #Python
Xadmin+rules实现多选行权限方式(级联效果)
Apr 07 #Python
Django Xadmin多对多字段过滤实例
Apr 07 #Python
解决Django部署设置Debug=False时xadmin后台管理系统样式丢失
Apr 07 #Python
解决Python中报错TypeError: must be str, not bytes问题
Apr 07 #Python
Pycharm及python安装详细步骤及PyCharm配置整理(推荐)
Jul 31 #Python
django 实现简单的插入视频
Apr 07 #Python
You might like
php常用字符串处理函数实例分析
2014/11/22 PHP
php抓取并保存网站图片的实现代码
2015/10/28 PHP
Yii2数据库操作常用方法小结
2017/05/04 PHP
ThinkPHP like模糊查询,like多匹配查询,between查询,in查询,一般查询书写方法
2018/09/26 PHP
php根据地址获取百度地图经纬度的实例方法
2019/09/03 PHP
JavaScript中创建类/对象的几种方法总结
2013/11/29 Javascript
jQuery实现HTML5 placeholder效果实例
2014/12/09 Javascript
JS实现放大、缩小及拖拽图片的方法【可兼容IE、火狐】
2016/08/23 Javascript
输入框点击时边框变色效果的实现方法
2016/12/26 Javascript
Angular的事件和表单详解
2016/12/26 Javascript
jQuery+HTML5实现弹出创意搜索框层
2016/12/29 Javascript
使用vue-cli编写vue插件的方法
2018/02/26 Javascript
vue实现的上传图片到数据库并显示到页面功能示例
2018/03/17 Javascript
Vue 按键修饰符处理事件的方法
2018/05/04 Javascript
浅谈HTTP 缓存的那些事儿
2018/10/17 Javascript
node中使用log4js4.x版本记录日志的方法
2019/08/20 Javascript
[01:03]PWL开团时刻DAY6——别打我
2020/11/05 DOTA
python读取注册表中值的方法
2013/04/08 Python
详解Python中映射类型(字典)操作符的概念和使用
2015/08/19 Python
Python 切分数组实例解析
2019/11/07 Python
python中if及if-else如何使用
2020/06/02 Python
Python 实现一个计时器
2020/07/28 Python
Selenium关闭INFO:CONSOLE提示的解决
2020/12/07 Python
html5 canvas 画图教程案例分析
2012/11/23 HTML / CSS
新加坡第一大健康与美容零售商:屈臣氏新加坡(Watsons Singapore)
2020/12/11 全球购物
实现strstr功能,即在父串中寻找子串首次出现的位置
2016/08/05 面试题
介绍一下代理模式(Proxy)
2014/10/17 面试题
元宵节主持词
2014/03/25 职场文书
代理协议书范本
2014/04/22 职场文书
大气污染防治方案
2014/05/19 职场文书
财务工作疏忽检讨书
2014/09/11 职场文书
2014年酒店工作总结与计划
2014/11/17 职场文书
2014年房产销售工作总结
2014/12/08 职场文书
《领导干部从政道德启示录》学习心得体会
2016/01/20 职场文书
CSS实现两列布局的N种方法
2021/08/02 HTML / CSS
vue如何在data中引入图片的正确路径
2022/06/05 Vue.js