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输出一个杨辉三角的例子
Jun 13 Python
python装饰器与递归算法详解
Feb 18 Python
简要讲解Python编程中线程的创建与锁的使用
Feb 28 Python
用Python将IP地址在整型和字符串之间轻松转换
Mar 22 Python
python数据封装json格式数据
Mar 04 Python
利用python实现在微信群刷屏的方法
Feb 21 Python
Django框架创建mysql连接与使用示例
Jul 29 Python
在Tensorflow中查看权重的实现
Jan 24 Python
Python基础之字符串操作常用函数集合
Feb 09 Python
Django Haystack 全文检索与关键词高亮的实现
Feb 17 Python
python实现暗通道去雾算法的示例
Sep 27 Python
用Python爬取某乎手机APP数据
Jun 15 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根据IP地址获取所在城市具体实现
2013/11/27 PHP
为PHP安装imagick时出现Cannot locate header file MagickWand.h错误的解决方法
2014/11/03 PHP
PHP解析RSS的方法
2015/03/05 PHP
php数据结构之顺序链表与链式线性表示例
2018/01/22 PHP
JS 获取浏览器和屏幕宽高等信息的实现思路及代码
2013/07/31 Javascript
利用javascript实现全部删或清空所选的操作
2014/05/27 Javascript
ECMAScript6的新特性箭头函数(Arrow Function)详细介绍
2014/06/07 Javascript
jQuery中click事件的定义和用法
2014/12/20 Javascript
js实现当复选框选择匿名登录时隐藏登录框效果
2015/08/14 Javascript
使用CamanJS在Web页面上处理图像的技巧
2015/08/18 Javascript
jQuery实现简易的天天爱消除小游戏
2015/10/16 Javascript
全国省市二级联动下拉菜单 js版
2016/05/10 Javascript
详解Angular的数据显示优化处理
2016/12/26 Javascript
Vue用v-for给src属性赋值的方法
2018/03/03 Javascript
jQuery+Cookie实现切换皮肤功能【附源码下载】
2018/03/25 jQuery
解决Antd Table表头加Icon和气泡提示的坑
2020/11/17 Javascript
[01:02:17]2014 DOTA2华西杯精英邀请赛 5 24 DK VS VG
2014/05/26 DOTA
Python高级应用实例对比:高效计算大文件中的最长行的长度
2014/06/08 Python
Python计算程序运行时间的方法
2014/12/13 Python
Python使用requests及BeautifulSoup构建爬虫实例代码
2018/01/24 Python
Python实现监控键盘鼠标操作示例【基于pyHook与pythoncom模块】
2018/09/04 Python
python递归法实现简易连连看小游戏
2020/03/25 Python
python的pyecharts绘制各种图表详细(附代码)
2019/11/11 Python
Django 项目通过加载不同env文件来区分不同环境
2020/02/17 Python
python实现图像拼接
2020/03/05 Python
以下的初始化有什么区别
2013/12/16 面试题
2014年迎新年联欢会活动策划方案
2014/02/26 职场文书
2014年光棍节活动策划方案(创意集锦)
2014/09/29 职场文书
加强作风建设工作总结
2014/10/23 职场文书
2015年党建工作总结
2015/03/30 职场文书
供应商食品安全承诺书
2015/04/29 职场文书
2015年小学语文工作总结
2015/05/25 职场文书
甲午风云观后感
2015/06/02 职场文书
接触艺术对孩子学习思维有益
2019/08/06 职场文书
【海涛dota】偶遇拉娜娅 质量局德鲁伊第一视角解说
2022/04/01 DOTA
小程序自定义轮播图圆点组件
2022/06/25 Javascript