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下的Mysql模块MySQLdb安装详解
Apr 09 Python
简单介绍Python中的filter和lambda函数的使用
Apr 07 Python
python实现简单的socket server实例
Apr 29 Python
python数据清洗系列之字符串处理详解
Feb 12 Python
利用Python查看目录中的文件示例详解
Aug 28 Python
python实现log日志的示例代码
Apr 28 Python
python对日志进行处理的实例代码
Oct 06 Python
Python 词典(Dict) 加载与保存示例
Dec 06 Python
Python使用Tkinter实现转盘抽奖器的步骤详解
Jan 06 Python
python爬虫模块URL管理器模块用法解析
Feb 03 Python
pandas to_excel 添加颜色操作
Jul 14 Python
python3爬虫GIL修改多线程实例讲解
Nov 24 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
PHP4实际应用经验篇(9)
2006/10/09 PHP
珊瑚虫IP库浅析
2007/02/15 PHP
php中用文本文件做数据库的实现方法
2008/03/27 PHP
PHP的文件操作与算法实现的面试题示例
2015/08/10 PHP
PHP+Ajax+JS实现多图上传
2016/05/07 PHP
程序员的表白神器“520”大声喊出来
2016/05/20 PHP
javascript替换已有元素replaceChild()使用介绍
2014/04/03 Javascript
JavaScript学习笔记之JS函数
2015/01/22 Javascript
easyui messager alert 三秒后自动关闭提示的实例
2016/11/07 Javascript
过期软件破解办法实例详解
2017/01/04 Javascript
微信小程序实现图片预加载组件
2017/01/18 Javascript
使用Vue自定义数字键盘组件(体验度极好)
2017/12/19 Javascript
js实现复制功能(多种方法集合)
2018/01/06 Javascript
小程序调用微信支付的方法
2019/09/26 Javascript
Python利用多进程将大量数据放入有限内存的教程
2015/04/01 Python
Python中str.format()详解
2017/03/12 Python
Tensorflow卷积神经网络实例进阶
2018/05/24 Python
Python实现调用另一个路径下py文件中的函数方法总结
2018/06/07 Python
详解Python 装饰器执行顺序迷思
2018/08/08 Python
Python设计模式之原型模式实例详解
2019/01/18 Python
python3.7 的新特性详解
2019/07/25 Python
pycharm实现猜数游戏
2020/12/07 Python
Python 实现集合Set的示例
2020/12/21 Python
python如何调用php文件中的函数详解
2020/12/29 Python
浅谈CSS3动画的回调处理
2016/07/21 HTML / CSS
乌克兰在线商店的价格比较:Price.ua
2019/07/26 全球购物
泰国时尚电商:POMELO Fashion
2020/03/11 全球购物
区域销售经理职责
2013/12/22 职场文书
十岁生日同学答谢词
2014/01/19 职场文书
美术教学感言
2014/02/22 职场文书
入股协议书范本
2014/04/14 职场文书
单方离婚协议书范本(2014版)
2014/09/30 职场文书
干部外出学习心得体会
2016/01/18 职场文书
Django展示可视化图表的多种方式
2021/04/08 Python
vue项目支付功能代码详解
2022/02/18 Vue.js
python工具dtreeviz决策树可视化和模型可解释性
2022/03/03 Python