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模拟enum枚举类型的方法小结
Apr 30 Python
各个系统下的Python解释器相关安装方法
Oct 12 Python
Win8.1下安装Python3.6提示0x80240017错误的解决方法
Jul 31 Python
浅谈Django的缓存机制
Aug 23 Python
python+numpy+matplotalib实现梯度下降法
Aug 31 Python
python opencv 二值化 计算白色像素点的实例
Jul 03 Python
Django中文件上传和文件访问微项目的方法
Apr 27 Python
解决python对齐错误的方法
Jul 16 Python
基于python爬取链家二手房信息代码示例
Oct 21 Python
Python基于百度API识别并提取图片中文字
Jun 27 Python
利用python实时刷新基金估值(摸鱼小工具)
Sep 15 Python
Python实现视频中添加音频工具详解
Dec 06 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获得文件扩展名三法
2006/11/25 PHP
php实现图片上传并进行替换操作
2016/03/15 PHP
Yii2数据库操作常用方法小结
2017/05/04 PHP
如何判断鼠标是否在DIV的区域内
2013/11/13 Javascript
使用jQuery中的when实现多个AJAX请求对应单个回调的例子分享
2014/04/23 Javascript
Javascript 完美运动框架(逐行分析代码,让你轻松了运动的原理)
2015/01/23 Javascript
jquery+CSS实现的水平布局多级网页菜单效果
2015/08/24 Javascript
node.js 中国天气预报 简单实现
2016/06/06 Javascript
谈谈JavaScript中的几种借用方法
2016/08/09 Javascript
jquery实现全选、不选、反选的两种方法
2016/09/06 Javascript
微信JS SDK接入的几点注意事项(必看篇)
2017/06/23 Javascript
nodejs 简单实现动态html的方法
2018/05/12 NodeJs
Vue+Node服务器查询Mongo数据库及页面数据传递操作实例分析
2019/12/20 Javascript
python正则表达式去掉数字中的逗号(python正则匹配逗号)
2013/12/25 Python
编写Python脚本来获取mp3文件tag信息的教程
2015/05/04 Python
Python 装饰器深入理解
2017/03/16 Python
pip matplotlib报错equired packages can not be built解决
2018/01/06 Python
Tornado高并发处理方法实例代码
2018/01/15 Python
python 去除txt文本中的空格、数字、特定字母等方法
2018/07/24 Python
浅谈python下tiff图像的读取和保存方法
2018/12/04 Python
啥是佩奇?使用Python自动绘画小猪佩奇的代码实例
2019/02/20 Python
详解django实现自定义manage命令的扩展
2019/08/13 Python
python爬虫beautifulsoup解析html方法
2020/12/07 Python
css3中检验表单的required,focus,valid和invalid样式
2014/02/21 HTML / CSS
ONLY德国官方在线商店:购买时尚女装
2017/09/21 全球购物
Etam德国:内衣精品店
2019/08/25 全球购物
经济实惠的名牌太阳镜和眼镜:Privé Revaux
2021/02/07 全球购物
农行实习自我鉴定
2013/09/22 职场文书
餐饮投资计划书
2014/04/25 职场文书
2014年党支部学习材料
2014/05/19 职场文书
地理科学专业自荐信
2014/09/01 职场文书
个人委托书范本
2014/09/13 职场文书
运动会400米加油稿(8篇)
2014/09/22 职场文书
商场圣诞节活动总结
2015/05/06 职场文书
2016年清明节期间群众祭祀活动工作总结
2016/04/01 职场文书
慰问信(范文3篇)
2019/10/23 职场文书