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从入门到精通(DAY 1)
Dec 20 Python
详解Python的Flask框架中的signals信号机制
Jun 13 Python
Python探索之URL Dispatcher实例详解
Oct 28 Python
python如何压缩新文件到已有ZIP文件
Mar 14 Python
Python使用min、max函数查找二维数据矩阵中最小、最大值的方法
May 15 Python
判断python字典中key是否存在的两种方法
Aug 10 Python
对python生成业务报表的实例详解
Feb 03 Python
linux下安装python3和对应的pip环境教程详解
Jul 01 Python
python图形绘制奥运五环实例讲解
Sep 14 Python
django表单中的按钮获取数据的实例分析
Jul 31 Python
Python调用系统命令os.system()和os.popen()的实现
Dec 31 Python
聊聊Python中关于a=[[]]*3的反思
Jun 02 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
连接到txt文本的超链接,不直接打开而是点击后下载的处理方法
2009/07/01 PHP
PHP学习之数组的定义和填充
2011/04/17 PHP
PHP 删除文件与文件夹操作 unlink()与rmdir()这两个函数的使用
2011/07/17 PHP
19个Android常用工具类汇总
2014/12/30 PHP
php session 写入数据库
2016/02/13 PHP
PHP会话控制实例分析
2016/12/24 PHP
利用php生成验证码
2017/02/23 PHP
laravel添加前台跳转成功页面示例
2019/10/22 PHP
Jquery选择器 $实现原理
2009/12/02 Javascript
基于jQuery的让非HTML5浏览器支持placeholder属性的代码
2011/05/24 Javascript
使用js操作css实现js改变背景图片示例
2014/03/10 Javascript
jQuery+PHP星级评分实现方法
2015/10/02 Javascript
JS实现浏览器状态栏文字闪烁效果的方法
2015/10/27 Javascript
基于jQuey实现鼠标滑过变色(整行变色)
2015/12/07 Javascript
jQuery添加和删除指定标签的方法
2015/12/16 Javascript
Websocket协议详解及简单实例代码
2016/12/12 Javascript
JavaScript实现瀑布流以及加载效果
2017/02/11 Javascript
nodejs中使用HTTP分块响应和定时器示例代码
2017/03/19 NodeJs
基于JavaScript实现的折半查找算法示例
2017/04/14 Javascript
微信小程序日期时间选择器使用方法
2018/02/01 Javascript
150行代码带你实现微信小程序中的数据侦听
2019/05/17 Javascript
vue实现鼠标经过动画
2019/10/16 Javascript
微信小程序利用云函数获取手机号码
2019/12/17 Javascript
vue vantUI tab切换时 list组件不触发load事件的问题及解决方法
2020/02/14 Javascript
区分vue-router的hash和history模式
2020/10/03 Javascript
Python fileinput模块使用实例
2015/05/28 Python
python嵌套字典比较值与取值的实现示例
2017/11/03 Python
python编程通过蒙特卡洛法计算定积分详解
2017/12/13 Python
Python实现图片尺寸缩放脚本
2018/03/10 Python
Python中一些不为人知的基础技巧总结
2018/05/19 Python
django的聚合函数和aggregate、annotate方法使用详解
2019/07/23 Python
Python实现中值滤波去噪方式
2019/12/18 Python
对pytorch的函数中的group参数的作用介绍
2020/02/18 Python
Django多数据库配置及逆向生成model教程
2020/03/28 Python
个人合伙协议书范本
2014/10/14 职场文书
Oracle中update和select 关联操作
2022/01/18 Oracle