使用python向服务器POST大文件
来源:互联网 发布:php打印出商品信息 编辑:程序博客网 时间:2024/06/06 11:02
使用python向服务器POST大文件
python 对http操作有几个库 urllib 、 urllib2 还有httplib
httplib比较偏底层 一般情况下使用urllib和urllib2就行了
NOTICE
在python3中urllib与urllib2被分割合并为了 urllib.request, urllib.parse, and urllib.error
httplib重命名为 http.client
分析http协议
python的这几个库中并没有提供直接上传文件的接口 我们先看下普通浏览器是怎么上传文件的 这里我在本地创建简单php程序 若有提交文件,则打印出文件相关的信息。否则显示一个上传表单表单
这里推荐一个抓包工具fildder 可以很方便的抓取htttp数据,并且直观的显示
下面就是抓取到的内容
从第1-13行就是请求消息http头部的内容,然后下面有个空行 比较重要的几行是
请求消息(Request message)有以下几部分组成
- 请求行(request line), 例如 GET /images/logo.png HTTP/1.1
- 请求头(Request Headers) 比如上面的 Host: localhost、 Content-Length: 295
- 空行
- 消息主体 message body
NOTICE
请求行与请求头必须以结尾,空行只能有不能有空格什么的 在HTTP/1.1协议中,除了Host 所有的请求头都是可选的(当然若上传文件的话,就必须设置了Content-Length和Content-Type了, 不然服务器收不到数据的,虽然也能成功响应)
这里message body的类型是multipart/form-data;
boundary 是随机的内容每次请求都不一样, Content-Type为 multipart/form-data; 可同时传输多项数据,而这些数据就是通过 boundary分割开来的
每一项的数据都是’–‘+boundary+换行开始 ,然后是Content-Disposition: form-data;name=”表单项名”
若是文件的话 还有个filename 以及Content-Type,接下来一个空行
最后’–‘+boundary+’–‘+换行结束
到这里整个http请求就结束了
模拟提交数据
其实http协议就是字符串按照约定规则拼接到一起 然后服务器再来解析得到数据 所以我们自己直接使用socket也能发起了一个http请求
但是有了urllib2我们可以省很多事 只需“拼接”内容部分就行了
url 可以是一个链接或者Request对象 data 就是我们要“拼接的内容”
下面是运行后的输出结果
php能正常接收传输的文件了 但是这里有个问题 ,我们拼接数据的时候使用的是
直接把文件内容读到内存中去了,小文件还好,要是几百M上G的文件还用这种方法就不行了,这样会把你的内存吃干。
所以我们就需要弄个变通的方法,让它一块一块的发送数据,读一点发送一点。 这几个库并没有提供类似的方法实现这一个功能,所以就需要自己动手了。
首先介绍一个python的关键字 yield 关于介绍python yield的文章可以查看Python yield 使用浅析 可以通过它来实现一个生成器(generator) 来不断的读取文件数据,而且是只在我们需要的时候读取
然后我重写了 httplib 中 HTTPConnection.send(data)使它可以接收一个generator,从里面取数据然后发送 下面是原版HTTPConnection.send的源码
它支持文件类型File Object 或者是一个字符串
下面是个重新版本
当然若想实现完美的文件提交,还需要做个封装,下面是一个简单的实现,还有写不完善的地方,post数据只能传文件,打算做个python lib封装一下
现在有很多现成的第三方库比如 poster Requests 可以实现这些功能了,但是由于是第三方库需要用户手动安装,在一个我需要上传大文件时有个回调功能,这样就能显示进度了。 等运行稳定了会添加到kuaipan cli 里面,就可以摆脱poster依赖
- 使用python向服务器POST大文件
- iOS中使用POST向服务器发送图片文件
- Python向服务器Post数据(可…
- Android客户端向Python服务器以POST方式传输数据
- VB.net 2005 向服务器POST信息(上传文件等)
- 通过POST请求向服务器上传文件源代码
- objective-c使用post方式向服务器传数据
- Android使用HttpURLConnection进行POST请求,向服务器上传数据
- 使用HttpURLConnection向服务器发送post和get请求
- 使用javascript以post的方式向服务器提交数据
- 使用HttpURLConnection向服务器发送post和get请求
- 使用libcurl以Post方式向HTTP服务器提交数据
- 使用HttpURLConnection向服务器发送post和get请求
- Okhttp使用post向服务器提交 sring[] 类型的数据
- 使用HttpURLConnection向服务器发送post和get请求
- Android-使用GET、POST、AsyncHttpClient向服务器提交数据
- 使用libcurl以Post方式向HTTP服务器提交数据
- Android使用HttpURLConnection向服务器发送post和get请求
- idea 使用
- iOS应用程序拨打电话
- Linux平台下WebRTC音视频获取(Javascript API)
- Java中Synchronized的用法
- Webview--如何让加载进来的页面自适应手机屏幕分辨率居中显示
- 使用python向服务器POST大文件
- C++项目中的extern "C" {}
- HTTP服务端接口模拟工具-HttpServerMockTool
- 全球调查显示独立的移动开发者更喜欢Android
- zabbix agent 类型所有key
- B. War of the Corporations
- Github 安卓项目版本控制指南
- UICollectionView
- Android程序设计:GridView显示图片