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实现简单状态框架的方法
Mar 19 Python
尝试用最短的Python代码来实现服务器和代理服务器
Jun 23 Python
python制作企业邮箱的爆破脚本
Oct 05 Python
python僵尸进程产生的原因
Jul 21 Python
利用Python查看目录中的文件示例详解
Aug 28 Python
python实现处理mysql结果输出方式
Apr 09 Python
如何在mac下配置python虚拟环境
Jul 06 Python
python如何对链表操作
Oct 10 Python
Python使用sql语句对mysql数据库多条件模糊查询的思路详解
Apr 12 Python
Python中的matplotlib绘制百分比堆叠柱状图,并为每一个类别设置不同的填充图案
Apr 20 Python
python神经网络学习 使用Keras进行回归运算
May 04 Python
Python通用验证码识别OCR库ddddocr的安装使用教程
Jul 07 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设计模式 Builder(建造者模式)
2011/06/26 PHP
PHP实现的sqlite数据库连接类
2014/12/12 PHP
Yii框架通过请求组件处理get,post请求的方法分析
2019/09/03 PHP
Thinkphp页面跳转设置跳转等待时间的操作
2019/10/16 PHP
直接生成打开窗口代码,不必下载
2008/05/14 Javascript
Javascript的闭包
2009/12/31 Javascript
ASP.NET中使用后端代码注册脚本 生成JQUERY-EASYUI的界面错位的解决方法
2010/06/12 Javascript
深入理解JavaScript系列(12) 变量对象(Variable Object)
2012/01/16 Javascript
javascript 控制input只允许输入的各种指定内容
2014/06/19 Javascript
asp.net+js实现金额格式化
2015/02/27 Javascript
包含中国城市的javascript对象实例
2015/08/03 Javascript
Jquery ajax 同步阻塞引起的UI线程阻塞问题
2015/11/17 Javascript
跟我学习javascript的循环
2015/11/18 Javascript
JavaScript获取当前cpu使用率的方法
2015/12/15 Javascript
JavaScript快速切换繁体中文和简体中文的方法及网站支持简繁体切换的绝招
2016/03/07 Javascript
JS 拼凑字符串的简单实例
2016/09/02 Javascript
vue组件中使用props传递数据的实例详解
2018/04/08 Javascript
JS返回页面时自动回滚到历史浏览位置
2018/09/26 Javascript
微信小程序导航栏跟随滑动效果的实现代码
2019/05/14 Javascript
JavaScript命名空间模式实例详解
2019/06/20 Javascript
vue+eslint+vscode配置教程
2019/08/09 Javascript
[02:40]2018年度DOTA2最佳新人-完美盛典
2018/12/16 DOTA
python中enumerate函数遍历元素用法分析
2016/03/11 Python
python中matplotlib实现最小二乘法拟合的过程详解
2017/07/11 Python
简单了解Django模板的使用
2017/12/20 Python
Python tkinter实现的图片移动碰撞动画效果【附源码下载】
2018/01/04 Python
Python实现的爬取百度文库功能示例
2019/02/16 Python
python+os根据文件名自动生成文本
2019/03/21 Python
详解三种方式实现平滑滚动页面到顶部的功能
2019/04/23 HTML / CSS
AmazeUI 平滑滚动效果的示例代码
2020/08/20 HTML / CSS
俄罗斯购买剧院和演唱会门票网站:Parter.ru
2019/11/09 全球购物
建筑院校毕业生求职信
2014/06/13 职场文书
物业消防安全责任书
2014/07/23 职场文书
大学生安全教育心得体会
2016/01/15 职场文书
浅析InnoDB索引结构
2021/04/05 MySQL
超越Nginx的Web服务器caddy优雅用法
2022/06/21 Servers