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实现baidu hi自动登录的代码
Feb 10 Python
python更新列表的方法
Jul 28 Python
Python实现的选择排序算法原理与用法实例分析
Nov 22 Python
Django 2.0版本的新特性抢先看!
Jan 05 Python
python如何定义带参数的装饰器
Mar 20 Python
详解Python3的TFTP文件传输
Jun 26 Python
python十进制和二进制的转换方法(含浮点数)
Jul 07 Python
不知道这5种下划线的含义,你就不算真的会Python!
Oct 09 Python
Python3 实现串口两进程同时读写
Jun 12 Python
pytz格式化北京时间多出6分钟问题的解决方法
Jun 21 Python
详解Tensorflow不同版本要求与CUDA及CUDNN版本对应关系
Aug 04 Python
python 使用csv模块读写csv格式文件的示例
Dec 02 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防止网站被攻击的应急代码
2015/10/21 PHP
Yii的Srbac插件用法详解
2016/07/14 PHP
Yii2框架制作RESTful风格的API快速入门教程
2016/11/08 PHP
php文件上传及下载附带显示文件及目录功能
2017/04/27 PHP
PHP中echo与print区别点整理
2021/03/09 PHP
JQuery实现表格中相同单元格合并示例代码
2013/06/26 Javascript
javascript生成随机颜色示例代码
2014/05/05 Javascript
JavaScript中获取鼠标位置相关属性总结
2014/10/11 Javascript
js中键盘事件实例简析
2015/01/10 Javascript
jQuery选择id属性带有点符号元素的方法
2015/03/17 Javascript
基于js中的原型、继承的一些想法
2016/08/10 Javascript
jQuery实现简洁的轮播图效果实例
2016/09/07 Javascript
利用jquery给指定的table动态添加一行、删除一行的方法
2016/10/12 Javascript
js获取地址栏中传递的参数(两种方法)
2017/02/08 Javascript
Vue瀑布流插件的使用示例
2018/09/19 Javascript
js实现随机点名程序
2020/09/17 Javascript
js get和post请求实现代码解析
2020/02/06 Javascript
python通过ElementTree操作XML获取结点读取属性美化XML
2013/12/02 Python
Python中文件操作简明介绍
2015/04/13 Python
轻量级的Web框架Flask 中模块化应用的实现
2017/09/11 Python
Python+tkinter使用40行代码实现计算器功能
2018/01/30 Python
Python针对给定字符串求解所有子序列是否为回文序列的方法
2018/04/21 Python
如何利用Boost.Python实现Python C/C++混合编程详解
2018/11/08 Python
python 实现在tkinter中动态显示label图片的方法
2019/06/13 Python
python频繁写入文件时提速的方法
2019/06/26 Python
Python从列表推导到zip()函数的5种技巧总结
2019/10/23 Python
python 如何使用find和find_all爬虫、找文本的实现
2020/10/16 Python
android面试问题与答案
2016/12/27 面试题
DIY蛋糕店的创业计划书范文
2013/12/26 职场文书
小学生田径运动会广播稿
2014/09/11 职场文书
学习朴航瑛老师爱岗敬业先进事迹思想汇报
2014/09/17 职场文书
党的群众路线教育实践活动督导组工作情况汇报
2014/10/28 职场文书
导师鉴定意见
2015/06/05 职场文书
开学第一周值周总结
2015/07/16 职场文书
2016年小学“感恩教师”主题队日活动总结
2016/04/01 职场文书
扩展多台相同的Web服务器
2021/04/01 Servers