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和shell变量互相传递的几种方法
Nov 20 Python
Python的网络编程库Gevent的安装及使用技巧
Jun 24 Python
python pands实现execl转csv 并修改csv指定列的方法
Dec 12 Python
python 扩展print打印文件路径和当前时间信息的实例代码
Oct 11 Python
python opencv 实现对图像边缘扩充
Jan 19 Python
Tensorflow 模型转换 .pb convert to .lite实例
Feb 12 Python
解决django的template中如果无法引用MEDIA_URL问题
Apr 07 Python
tensorflow使用freeze_graph.py将ckpt转为pb文件的方法
Apr 22 Python
Python3 pywin32模块安装的详细步骤
May 26 Python
opencv 图像加法与图像融合的实现代码
Jul 08 Python
Python爬虫获取op.gg英雄联盟英雄对位胜率的源码
Jan 29 Python
django上传文件的三种方式
Apr 29 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 Warning: PHP Startup: Unable to load dynamic library \ D:/php5/ext/php_mysqli.dll\
2012/06/17 PHP
PHP中使用asort进行中文排序失效的问题处理
2014/08/18 PHP
PHP处理Oracle的CLOB实例
2014/11/03 PHP
PHP7扩展开发教程之Hello World实现方法示例
2017/08/03 PHP
PHP实现单条sql执行多个数据的insert语句方法
2019/10/11 PHP
静态图片的十一种滤镜效果--不支持Ie7及非IE浏览器。
2007/03/06 Javascript
浏览器窗口加载和大小改变事件示例
2014/02/27 Javascript
Flexigrid在IE下不显示数据的有效处理方法
2014/09/04 Javascript
JavaScript实现基于Cookie的存储类实例
2015/04/10 Javascript
JavaScript实现动画打开半透明提示层的方法
2015/04/21 Javascript
JavaScript获取DOM元素的11种方法总结
2015/04/25 Javascript
一系列Bootstrap导航条使用方法分享
2016/04/29 Javascript
jquery实现倒计时小应用
2017/09/19 jQuery
基于node打包可执行文件工具_Pkg使用心得分享
2018/01/24 Javascript
element-ui的回调函数Events的用法详解
2018/10/16 Javascript
[02:10]DOTA2亚洲邀请赛 EG战队出场宣传片
2015/02/07 DOTA
老生常谈进程线程协程那些事儿
2017/07/24 Python
python保存二维数组到txt文件中的方法
2018/11/15 Python
在Python 字典中一键对应多个值的实例
2019/02/03 Python
python协程之动态添加任务的方法
2019/02/19 Python
Python3操作MongoDB增册改查等方法详解
2020/02/10 Python
Python拼接字符串的7种方式详解
2020/03/19 Python
Python2 与Python3的版本区别实例分析
2020/03/30 Python
python如何解析复杂sql,实现数据库和表的提取的实例剖析
2020/05/15 Python
酒店副总岗位职责
2013/12/24 职场文书
师范教师大学生职业生涯规划范文
2014/01/05 职场文书
老师对学生的评语
2014/04/18 职场文书
员工安全责任书范本
2014/07/24 职场文书
三八妇女节超市活动方案
2014/08/18 职场文书
感恩祖国演讲稿
2014/09/09 职场文书
乡镇组织委员个人整改措施
2014/09/16 职场文书
工作收入住址证明
2014/10/28 职场文书
幼儿园安全管理制度
2015/08/05 职场文书
解析:创业计划书和商业计划书二者之间到底有什么区别
2019/08/14 职场文书
Oracle设置DB、监听和EM开机启动的方法
2021/04/25 Oracle
修改MySQL的默认密码的四种小方法
2021/05/26 MySQL