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实现向QQ群成员自动发邮件的方法
Nov 19 Python
python通过微信发送邮件实现电脑关机
Jun 20 Python
Django框架实现逆向解析url的方法
Jul 04 Python
python+pandas+时间、日期以及时间序列处理方法
Jul 10 Python
在python中利用numpy求解多项式以及多项式拟合的方法
Jul 03 Python
python 随机森林算法及其优化详解
Jul 11 Python
python Django里CSRF 对应策略详解
Aug 05 Python
解决Tensorboard 不显示计算图graph的问题
Feb 15 Python
python统计文章中单词出现次数实例
Feb 27 Python
一文搞懂如何实现Go 超时控制
Mar 30 Python
python实现批量移动文件
Apr 05 Python
python数字图像处理:图像简单滤波
Jun 28 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实现ODBC数据分页显示一例
2006/10/09 PHP
PHP 魔术函数使用说明
2010/05/14 PHP
深入解析fsockopen与pfsockopen的区别
2013/07/05 PHP
一漂亮的PHP图片验证码实例
2014/03/21 PHP
PHP三元运算的2种写法代码实例
2014/05/12 PHP
PHP SESSION的增加、删除、修改、查看操作
2015/03/20 PHP
php函数重载的替代方法--伪重载详解
2015/05/08 PHP
PHP生成随机密码方法汇总
2015/08/27 PHP
使用PHPMailer发送邮件实例
2017/02/15 PHP
详解PHP素材图片上传、下载功能
2019/04/12 PHP
laravel-admin 后台表格筛选设置默认的查询日期方法
2019/10/03 PHP
一份老外写的XMLHttpRequest代码多浏览器支持兼容性
2007/01/11 Javascript
JS自动适应的图片弹窗实例
2013/06/29 Javascript
JavaScript中读取和保存文件实例
2014/05/08 Javascript
Jquery仿IGoogle实现可拖动窗口示例代码
2014/08/22 Javascript
JavaScript中SetInterval与setTimeout的用法详解
2015/11/10 Javascript
JavaScript原生数组Array常用方法
2017/04/06 Javascript
详解vue axios二次封装
2018/07/22 Javascript
单线程JavaScript实现异步过程详解
2020/05/19 Javascript
Vue 同步异步存值取值实现案例
2020/08/05 Javascript
python分析apache访问日志脚本分享
2015/02/26 Python
Python socket实现简单聊天室
2018/04/01 Python
解决python中画图时x,y轴名称出现中文乱码的问题
2019/01/29 Python
python自动化实现登录获取图片验证码功能
2019/11/20 Python
PyCharm 2020.2下配置Anaconda环境的方法步骤
2020/09/23 Python
12个不为大家熟知的HTML5设计小技巧
2016/06/02 HTML / CSS
html5调用app分享功能示例(WebViewJavascriptBridge)
2018/03/21 HTML / CSS
泰国综合购物网站:Lazada泰国
2018/04/09 全球购物
linux面试题参考答案(10)
2013/11/04 面试题
便利店投资的创业计划书
2014/01/12 职场文书
士力架广告词
2014/03/20 职场文书
干部选拔任用方案
2014/05/26 职场文书
员工辞职信怎么写
2015/02/27 职场文书
大学四年个人总结
2015/03/03 职场文书
2016国庆节67周年寄语
2015/12/07 职场文书
Python 可迭代对象 iterable的具体使用
2021/08/07 Python