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实现更改图片尺寸大小的方法(基于Pillow包)
Sep 19 Python
用matplotlib画等高线图详解
Dec 14 Python
使用Python实现微信提醒备忘录功能
Dec 04 Python
celery4+django2定时任务的实现代码
Dec 23 Python
浅谈Python中的可迭代对象、迭代器、For循环工作机制、生成器
Mar 11 Python
从0开始的Python学习014面向对象编程(推荐)
Apr 02 Python
Python 3.6 中使用pdfminer解析pdf文件的实现
Sep 25 Python
python 下 CMake 安装配置 OPENCV 4.1.1的方法
Sep 30 Python
基于plt.title无法显示中文的快速解决
May 16 Python
什么是python的必选参数
Jun 21 Python
python 对xml解析的示例
Feb 27 Python
Python Pandas 删除列操作
Mar 16 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+Tidy-完美的XHTML纠错+过滤
2007/04/10 PHP
php知道与问问的采集插件代码
2010/10/12 PHP
PHP垃圾回收机制引用计数器概念分析
2013/06/24 PHP
php递归删除目录下的文件但保留的实例分享
2014/05/10 PHP
php技术实现加载字体并保存成图片
2015/07/27 PHP
php处理复杂xml数据示例
2016/07/11 PHP
Yii框架布局文件的动态切换操作示例
2019/11/11 PHP
a标签的href和onclick 的事件的区别介绍
2013/07/26 Javascript
js编写trim()函数及正则表达式的运用
2013/10/24 Javascript
JQuery实现table行折叠效果以JSON做数据源
2014/05/26 Javascript
PHP结合jQuery实现红蓝投票功能特效
2015/07/22 Javascript
解决nodejs中使用http请求返回值为html时乱码的问题
2017/02/18 NodeJs
使用bootstrap插件实现模态框效果
2017/05/10 Javascript
JavaScript实现设置默认日期范围为最近40天的方法分析
2017/07/12 Javascript
js实现图片放大展示效果
2017/08/30 Javascript
深入理解ES6之数据解构的用法
2018/01/13 Javascript
angularJs复选框checkbox选中进行ng-show显示隐藏的方法
2018/10/08 Javascript
vue+elementUI实现表格关键字筛选高亮
2020/10/26 Javascript
vue路由缓存的几种实现方式小结
2020/02/02 Javascript
js轮播图之旋转木马效果
2020/10/13 Javascript
在Python3中初学者应会的一些基本的提升效率的小技巧
2015/03/31 Python
python多进程实现进程间通信实例
2017/11/24 Python
python实现二叉查找树实例代码
2018/02/08 Python
Python实现的网页截图功能【PyQt4与selenium组件】
2018/07/12 Python
python实现三维拟合的方法
2018/12/29 Python
python opencv实现图像边缘检测
2019/04/29 Python
Django forms表单 select下拉框的传值实例
2019/07/19 Python
Python实现网页截图(PyQT5)过程解析
2019/08/12 Python
python爬虫 urllib模块反爬虫机制UA详解
2019/08/20 Python
利用 Flask 动态展示 Pyecharts 图表数据方法小结
2019/09/04 Python
python使用自定义钉钉机器人的示例代码
2020/06/24 Python
阿里健康官方海外旗舰店:阿里健康国际自营
2017/11/24 全球购物
不同意离婚上诉状
2015/05/23 职场文书
高中数学教学反思范文
2016/02/18 职场文书
新店开业策划方案怎么书写?
2019/07/05 职场文书
vue递归实现树形组件
2022/07/15 Vue.js