python使用requests库通过proxy代理post上传文件

  • Post author:
  • Post category:python




python使用requests库通过proxy代理post上传文件

python通过http post的方式上传文件到服务器有多种方式,使用urllib2库,poster库和requests库均可实现。此处由于环境的限制,使用requests库来实现。先上代码,我使用的是python2进行的编写

import requests
import json

f = open("./abc", "rb")
url = 'http://100.11.12.13:8989/upload'
files = {'file' : f } 
headers = { "Host" : "100.11.12.13:8989" }
proxy =  { 'http' : "192.168.1.156:8012"}
post_data = {}
post_data["name"] = "bob"
data = json.dumps(post_data).encode("utf-8")

r = request.post(url,proxies=proxy,data=data,files=files,headers=headers)
print(r.text)
f.close();

此处主要涉及如下方面

  1. 文件上传

    通过post接口files参数上传,参数为字典结构,file为key值,f打开的句柄表示要上传的文件内容,此处使用了最简洁的形式,根据博客

    requests上传多个文件

    ,官方 推荐如下结构
{
  "field1" : ("filename1", open("filePath1", "rb")),
  "field2" : ("filename2", open("filePath2", "rb"), "image/jpeg"),
  "field3" : ("filename3", open("filePath3", "rb"), "image/jpeg", {"refer" : "localhost"})
}

在上面的最简模式中 filename 就是filepath中的文件名。该接口参数字典可以以这种方式,支持同时上传不同key值的多个文件。

  1. 代理设置
proxy =  { 'http' : "192.168.1.156:8012"}

该行是设置目的代理为 192.168.1.156的8012端口上的服务,我在这个位置部署了一台windows上的nginx服务器。对上传请求做代理转发。此处的 key值指定的是协议的类型,即使是http,也不限制是80端口,实际上我上述的请求服务器目的端口就不是80端口,对应的需要通过https协议进行上传时,需将key值指定为

https

,同时可能需要设置字段,

verify=False.

  1. 头部信息设置

    但上述的设置仍然无法完成通过proxy代理进行post文件的上传,我是在python 2.7.3 版本,会提示对应页面无法访问,通过抓包发现,虽然 url中请求的目的端口是8989端口,但是Host中的信息是只有100.11.12.13,即不含有端口的信息,而nginx在进行代理转发时,是依赖Host中的信息进行代理转发的,如下
        location / {
            proxy_pass http://$http_host$request_uri;
        }

此处应是该版本requests库的实现缺陷,故而需要在headers中再指定,headers = { “Host” : “100.11.12.13:8989” }。才能够再nginx代理转发时完成转发。

  1. nginx代理配置

    nginx代理除了完成上述配置外,因post上传内容可能较大,可能返回nginx 413错误,即Request Entity Too large,仍然需要在http模块中增加 client上传的body的配置信息如下:
http {
...
    client_max_body_size 100M;
...
}

client_max_body_size该值默认为1MB,为请求正文的允许大小,判断的是Content-Length字段的值。

参考

http://cn.python-requests.org/zh_CN/latest/user/quickstart.html



版权声明:本文为u010050543原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。