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标准异常和异常处理详解
Feb 02 Python
使用python绘制常用的图表
Aug 27 Python
Python3.6简单操作Mysql数据库
Sep 12 Python
Python numpy 提取矩阵的某一行或某一列的实例
Apr 03 Python
Python3实现爬取简书首页文章标题和文章链接的方法【测试可用】
Dec 11 Python
python实现银联支付和支付宝支付接入
May 07 Python
python 绘制拟合曲线并加指定点标识的实现
Jul 10 Python
python字典的常用方法总结
Jul 31 Python
Python实现直方图均衡基本原理解析
Aug 08 Python
Python小整数对象池和字符串intern实例解析
Mar 21 Python
python简单的三元一次方程求解实例
Apr 02 Python
Django 实现jwt认证的示例
Apr 30 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
星际玩家的三大定律
2020/03/04 星际争霸
PHP网上调查系统
2006/10/09 PHP
yii分页组件用法实例分析
2015/12/28 PHP
学习js所必须要知道的一些
2007/03/07 Javascript
js 分栏效果实现代码
2009/08/29 Javascript
表头固定(利用jquery实现原理介绍)
2012/11/08 Javascript
JavaScript中的onerror事件概述及使用
2013/04/01 Javascript
JS实现div内部的文字或图片自动循环滚动代码
2013/04/19 Javascript
跟我学Nodejs(一)--- Node.js简介及安装开发环境
2014/05/20 NodeJs
JQuery中使用on方法绑定hover事件实例
2014/12/09 Javascript
js实现的二分查找算法实例
2016/01/21 Javascript
基于JS实现的笛卡尔乘积之商品发布
2016/05/13 Javascript
Node.js的环境安装配置(使用nvm方式)
2016/10/11 Javascript
微信小程序 实战实例开发流程详细介绍
2017/01/05 Javascript
基于Vue2实现的仿手机QQ单页面应用功能(接入聊天机器人 )
2017/03/30 Javascript
JS实现的简单表单验证功能完整实例
2017/10/14 Javascript
小程序富文本提取图片可放大缩小
2020/05/26 Javascript
解决echarts图表使用v-show控制图表显示不全的问题
2020/07/19 Javascript
[43:32]Winstrike vs VGJ.S 2018国际邀请赛淘汰赛BO3 第一场 8.23
2018/08/24 DOTA
python基本语法练习实例
2017/09/19 Python
Python OpenCV 直方图的计算与显示的方法示例
2018/02/08 Python
淘宝秒杀python脚本 扫码登录版
2019/09/19 Python
python的命名规则知识点总结
2019/10/04 Python
基于Python 的语音重采样函数解析
2020/07/06 Python
django使用channels实现通信的示例
2020/10/19 Python
NBA欧洲商店(法国):NBA Europe Store FR
2016/10/19 全球购物
瑞典度假品牌:OAS
2019/05/28 全球购物
凌阳科技股份有限公司C++程序员面试题笔试题
2014/11/20 面试题
产品质量承诺书范文
2014/03/27 职场文书
买卖车协议书
2014/04/21 职场文书
学生会感恩节活动方案
2014/10/11 职场文书
群众路线组织生活会发言材料
2014/10/17 职场文书
入党积极分子对十八届四中全会期盼的思想汇报
2014/10/17 职场文书
抗洪救灾感谢信
2015/01/22 职场文书
公司趣味运动会开幕词
2016/03/04 职场文书
Mysql 设置boolean类型的操作
2021/06/04 MySQL