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 相关文章推荐
github配置使用指南
Nov 18 Python
Python标准库之循环器(itertools)介绍
Nov 25 Python
Python中的条件判断语句与循环语句用法小结
Mar 21 Python
Python基础篇之初识Python必看攻略
Jun 23 Python
利用python发送和接收邮件
Sep 27 Python
解决sublime+python3无法输出中文的问题
Dec 12 Python
Python基于datetime或time模块分别获取当前时间戳的方法实例
Feb 19 Python
python的pytest框架之命令行参数详解(上)
Jun 27 Python
搭建python django虚拟环境完整步骤详解
Jul 08 Python
Python中的几种矩阵乘法(小结)
Jul 10 Python
python 机器学习的标准化、归一化、正则化、离散化和白化
Apr 16 Python
Python装饰器的练习题
Nov 23 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
使用adodb lite解决问题
2006/12/31 PHP
深入PHP变量存储的详解
2013/06/13 PHP
PHP验证码函数代码(简单实用)
2013/09/29 PHP
php实现格式化多行文本为Js可用格式
2015/04/15 PHP
PHP+swoole实现简单多人在线聊天群发
2016/01/19 PHP
JavaScript语言中的Literal Syntax特性分析
2007/03/08 Javascript
Javascript 类型转换方法
2010/10/24 Javascript
js实现拖拽 闭包函数详细介绍
2012/11/25 Javascript
js用Date对象处理时间实现思路及代码
2013/01/31 Javascript
jQuery焦点图切换特效插件封装实例
2013/08/18 Javascript
js读取json的两种常用方法示例介绍
2014/10/19 Javascript
javascript实现回到顶部特效
2015/05/06 Javascript
javascript如何操作HTML下拉列表标签
2015/08/20 Javascript
利用jsonp与代理服务器方案解决跨域问题
2017/09/14 Javascript
基于js原生和ajax的get和post方法以及jsonp的原生写法实例
2017/10/16 Javascript
jquery一键控制checkbox全选、反选或全不选
2017/10/16 jQuery
深入理解Vue官方文档梳理之全局API
2017/11/22 Javascript
用node-webkit把web应用打包成桌面应用(windows环境)
2018/02/01 Javascript
Bootstrap模态对话框中显示动态内容的方法
2018/08/10 Javascript
如何用原生js写一个弹窗消息提醒插件
2019/05/24 Javascript
[44:40]Serenity vs Pain 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
[02:04]2020年夜魇暗潮预告片
2020/10/30 DOTA
Python实现大文件排序的方法
2015/07/10 Python
简单实现python进度条脚本
2017/12/18 Python
Python %r和%s区别代码实例解析
2020/04/03 Python
在Keras中实现保存和加载权重及模型结构
2020/06/15 Python
python中逻辑与或(and、or)和按位与或异或(&、|、^)区别
2020/08/05 Python
eHarmony英国:全球领先的认真恋爱约会平台之一
2020/11/16 全球购物
仓管员岗位职责范文
2013/11/08 职场文书
大学生简历的个人自我评价
2013/12/04 职场文书
置业顾问岗位职责
2014/03/02 职场文书
分公司经理任命书
2014/06/05 职场文书
领导班子三严三实心得体会
2014/10/13 职场文书
推销搭讪开场白
2015/05/28 职场文书
光荣之路观后感
2015/06/12 职场文书
暑期社会实践新闻稿
2015/07/17 职场文书