Python发送form-data请求及拼接form-data内容的方法


Posted in Python onMarch 05, 2016

 网上关于使用python 的发送multipart/form-data的方法,多半是采用

ulrlib2 的模拟post方法,如下:

import urllib2

boundary='-------------------------7df3069603d6' 
data=[] 
data.append('--%s' % boundary) 
data.append('Content-Disposition: form-data; name="app_id"\r\n') 
data.append('xxxxxx') 
data.append('--%s' % boundary) 
data.append('Content-Disposition: form-data; name="version"\r\n') 
data.append('xxxxx') 
data.append('--%s' % boundary) 
data.append('Content-Disposition: form-data; name="platform"\r\n') 
data.append('xxxxx') 
data.append('--%s' % boundary) 
data.append('Content-Disposition: form-data; name="libzip"; filename="C:\Users\danwang3\Desktop\libmsc.zip"') 
data.append('Content-Type: application/octet-stream\r\n') 
 
fr=open('C:\Users\danwang3\Desktop\libmsc.zip') 
content=fr.read() 
data.append(content) 
print content 
fr.close() 
data.append('--%s--\r\n'%boundary) 
httpBody='\r\n'.join(data) 
 
print type(httpBody) 
print httpBody 
 
postDataUrl='http://xxxxxxxx' 
req=urllib2.Request(postDataUrl,data=httpBody)

经过测试,使用上述方法发送一段二进制文件的时候,服务器报错,数据有问题!

问题就出在    '\r\n'.join(data)的编码,data内部拥有二进制数据,通过这种编码,可能是把数据转换为utf-8格式,当然有问题。

搜索了很多资料,查到可以使用requests库提交multipart/form-data 格式的数据

一个multipart/form-data 的表单数据,在http里面抓包如下:

#Content-Disposition: form-data;name="app_id"


 123456

#-----------------------------7df23df2a0870

#Content-Disposition: form-data;name="version"

 

 2256

 -----------------------------7df23df2a0870

 Content-Disposition:form-data; name="platform"

 

 ios

 -----------------------------7df23df2a0870

 Content-Disposition: form-data;name="libzip";filename="C:\Users\danwang3\Desktop\libmsc.zip"

 Content-Type: application/x-zip-compressed

 

 <二进制文件数据未显示>

---------------------------7df23df2a0870—

上述数据在requests里面可以模拟为:

files={'app_id':(None,'123456'),
  'version':(None,'2256'),
  'platform':(None,'ios'),
  'libzip':('libmsc.zip',open('C:\Users\danwang3\Desktop\libmsc.zip','rb'),'application/x-zip-compressed')
 }

发送上述post请求,也就是简单的

response=requests.post(url,files=files)

就这么简单

在官方网站上,requests模拟一个表单数据的格式如下:

files = {'name': (<filename>, <file object>,<content type>, <per-part headers>)}

这一行模拟出来的post数据为:

Content-Disposition: form-data; name='name';filename=<filename>
Content-Type: <content type>
 
<file object>
--boundary

如果filename 和 content-Type不写,那么响应模拟post的数据就不会有二者。

通常使用requests 不像使用urllib2那样可以自动管理cookie,不过如果获取到cookie

可以在requests请求里面一并将cookie发送出去

requests使用的cookie格式如下:

newCookie={}
newCookie['key1']='value1'
newCookie['key2]='value2'
newCookie['key3']='value3'

发送cookie可以使用:

response=requests.post(url,cookies=newCookie)

这样就可以了

拼接form-data的post内容

#!\urs\bin\env python 
#encoding:utf-8    #设置编码方式  
  
from http2 import http 
import urllib 
 
def ReadFileAsContent(filename): 
  #print filename 
  try: 
    with open(filename, 'rb') as f: 
      filecontent = f.read() 
  except Exception, e: 
    print 'The Error Message in ReadFileAsContent(): ' + e.message  
    return '' 
  return filecontent 
 
 
def get_content_type(filename): 
  import mimetypes 
  return mimetypes.guess_type(filename)[0] or 'application/octet-stream' 
 
def isfiledata(p_str):  
  import re 
   
  r_c = re.compile("^f'(.*)'$") 
  rert = r_c.search(str(p_str)) 
  #rert = re.search("^f'(.*)'$", p_str) 
  if rert: 
    return rert.group(1) 
  else: 
    return None 
   
def encode_multipart_formdata(fields): 
  ''''' 
      该函数用于拼接multipart/form-data类型的http请求中body部分的内容 
      返回拼接好的body内容及Content-Type的头定义 
  ''' 
  import random 
  import os 
  BOUNDARY = '----------%s' % ''.join(random.sample('0123456789abcdef', 15)) 
  CRLF = '\r\n' 
  L = [] 
  for (key, value) in fields: 
    filepath = isfiledata(value) 
    if filepath: 
      L.append('--' + BOUNDARY) 
      L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, os.path.basename(filepath))) 
      L.append('Content-Type: %s' % get_content_type(filepath)) 
      L.append('') 
      L.append(ReadFileAsContent(filepath))  
    else: 
      L.append('--' + BOUNDARY) 
      L.append('Content-Disposition: form-data; name="%s"' % key) 
      L.append('') 
      L.append(value)  
  L.append('--' + BOUNDARY + '--') 
  L.append('') 
  body = CRLF.join(L) 
  content_type = 'multipart/form-data; boundary=%s' % BOUNDARY 
  return content_type, body

其中需要注意的是文件数据的字典值,其格式为f'/path/to/file',具体调用的形式如下:

form_data = [('gShopID','489'),("addItems", r"f'D:\case3guomei.xml'"), ('validateString', '92c99a2a36f47c6aa2f0019caa0591d2')] 
form_data_re = encode_multipart_formdata(form_data) 
print form_data_re

返回的内容是一个元组,第一个参数是请求头中Content-Type的值,第二个是具体post的内容。然后使用httplib的post方法就可以发送了。

Python 相关文章推荐
python实现的生成随机迷宫算法核心代码分享(含游戏完整代码)
Jul 11 Python
Python中的类学习笔记
Sep 23 Python
Python脚本实现网卡流量监控
Feb 14 Python
详细解读Python中的__init__()方法
May 02 Python
python中getaddrinfo()基本用法实例分析
Jun 28 Python
对命令行模式与python交互模式介绍
May 12 Python
python pandas cumsum求累计次数的用法
Jul 29 Python
Python数据可视化:箱线图多种库画法
Nov 06 Python
python支持多继承吗
Jun 19 Python
keras 两种训练模型方式详解fit和fit_generator(节省内存)
Jul 03 Python
快速解释如何使用pandas的inplace参数的使用
Jul 23 Python
python中数组和列表的简单实例
Mar 25 Python
Python多线程爬虫简单示例
Mar 04 #Python
使用Python来开发Markdown脚本扩展的实例分享
Mar 04 #Python
使用py2exe在Windows下将Python程序转为exe文件
Mar 04 #Python
用Python编写简单的微博爬虫
Mar 04 #Python
python相似模块用例
Mar 04 #Python
Python程序中用csv模块来操作csv文件的基本使用教程
Mar 03 #Python
举例简单讲解Python中的数据存储模块shelve的用法
Mar 03 #Python
You might like
PHP中的函数-- foreach()的用法详解
2013/06/24 PHP
解析PHP中VC6 X86和VC9 X86的区别及 Non Thread Safe的意思
2013/06/28 PHP
浅析get与post的一些特殊情况
2014/07/28 PHP
javascript+php实现根据用户时区显示当地时间的方法
2015/03/11 PHP
Laravel 5框架学习之日期,Mutator 和 Scope
2015/04/08 PHP
Laravel 5.5 的自定义验证对象/类示例代码详解
2017/08/29 PHP
jQuery AJAX 调用WebService实现代码
2010/03/24 Javascript
数组方法解决JS字符串连接性能问题有争议
2011/01/12 Javascript
JQuery中使用ajax传输超大数据的解决方法
2014/07/14 Javascript
Javascript基础教程之定义和调用函数
2015/01/18 Javascript
AngularJS语法详解
2015/01/23 Javascript
基于jQuery实现最基本的淡入淡出效果实例
2015/02/02 Javascript
简介JavaScript中的getSeconds()方法的使用
2015/06/10 Javascript
JavaScript检测并限制复选框选中个数的方法
2015/08/12 Javascript
jquery验证邮箱格式并显示提交按钮
2015/11/07 Javascript
基于javascript代码检测访问网页的浏览器呈现引擎、平台、Windows操作系统、移动设备和游戏系统
2015/12/03 Javascript
使用jQuery实现Web页面换肤功能的要点解析
2016/05/12 Javascript
微信和qq时间格式模板实例详解
2016/10/21 Javascript
JS中用childNodes获取子元素换行会产生一个子元素
2016/12/08 Javascript
Javascript实现运算符重载详解
2018/04/07 Javascript
vue使用canvas实现移动端手写签名
2020/09/22 Javascript
详解实现vue的数据响应式原理
2021/01/20 Vue.js
Python+request+unittest实现接口测试框架集成实例
2018/03/16 Python
Python3.5常见内置方法参数用法实例详解
2019/04/29 Python
python3中pip3安装出错,找不到SSL的解决方式
2019/12/12 Python
jupyter notebook 多环境conda kernel配置方式
2020/04/10 Python
美国指甲油品牌:Deco Miami
2017/01/30 全球购物
网络工程专业毕业生推荐信
2013/10/28 职场文书
物流专业毕业生推荐信范文
2013/11/18 职场文书
你懂得怎么写自荐信吗?
2013/12/27 职场文书
校园报刊亭创业计划书
2014/01/02 职场文书
应届生求职自荐信
2014/07/04 职场文书
车辆转让协议书
2014/09/24 职场文书
2014年超市员工工作总结
2014/11/18 职场文书
校长师德表现自我评价
2015/03/05 职场文书
家长通知书家长意见
2015/06/03 职场文书