【问题标题】:python urllib2 file send problempython urllib2文件发送问题
【发布时间】:2011-06-21 05:55:47
【问题描述】:

我想通过 python 将文件发布到服务器,为此我需要将此文件命名为“xmlfile”,以便服务器识别输入。

import urllib2

url = "http://somedomain"
to_send = open('test.xml').read()
data = {}
data['xmlfile'] = to_send
f = urllib2.urlopen(url, data)

这不起作用,另外,我怎样才能检索响应并保存在某个地方?

换句话说,我想像使用 Curl 一样做动作:

curl.exe http://somedomain -F xmlfile=@test.xml -o response.html

【问题讨论】:

标签: python curl urllib2


【解决方案1】:

我刚刚阅读了 nimrodm 提到的问题。一个答案提到了海报模块。 该模块可以进行multipart/form-data 编码,所以如果向您的项目添加另一个依赖项不是问题,我会使用海报模块。


这并不像应有的那么简单。网上有一个代码 sn-p 漂浮在我的代码中,它可以解决问题。您可能必须根据需要对其进行调整。

class RequestWithMethod(urllib2.Request):
    def __init__(self, method, *args, **kwargs):
        self._method = method
        urllib2.Request.__init__(self, *args, **kwargs)

    def get_method(self):
        return self._method

class RestRequest(object):
    def __init__(self, base_url):
        self.base_url = base_url

    def request(self, url, method, headers={"Accept" : "application/json"}, data=None, json_response=True):
        request = RequestWithMethod(url='{0}{1}{2}'.format(self.base_url, root_url(), url),
                                    method=method,
                                    headers=headers)

        if data != None:
            data = urllib.urlencode(data)

        response = urllib2.urlopen(request, data=data).read()

        if json_response:
            return from_json(response)
        else:
            return response

    def GET(self, url, **kwargs):
        return self.request(url, 'GET', **kwargs)

    def POST(self, url, **kwargs):
        return self.request(url, 'POST', **kwargs)

    def POST_FILE(self, url, file, headers={"Accept" : "application/json"}, data={}, **kwargs):
        content_type, body = encode_multipart_formdata(data, file)

        headers['Content-type'] = content_type
        headers['Content-length'] = str(len(body))

        request = RequestWithMethod(url='{0}{1}{2}'.format(self.base_url, root_url(), url),
                                    data=body,
                                    method='POST',
                                    headers=headers)

        return from_json(urllib2.urlopen(request).read())

    def PUT(self, url, **kwargs):
        return self.request(url, 'PUT', **kwargs)

    def DELETE(self, url, **kwargs):
        return self.request(url, 'DELETE', **kwargs)

def encode_multipart_formdata(data, file):
    boundary = '----------ThIs_Is_tHe_bouNdaRY_$'
    L = []
    for key, value in data.items():
        L.append('--' + boundary)
        L.append('Content-Disposition: form-data; name="{0}"'.format(key))
        L.append('')
        L.append(value)

    key, filename, value = file
    L.append('--' + boundary)
    L.append('Content-Disposition: form-data; name="{0}"; filename="{1}"'.format(key, filename))
    content_type = mimetypes.guess_type(filename)[0] or 'application/octet-stream'
    L.append('Content-Type: {0}'.format(content_type))
    L.append('')
    L.append(value)

    L.append('--' + boundary + '--')
    L.append('')
    body = '\r\n'.join(L)
    content_type = 'multipart/form-data; boundary={0}'.format(boundary)

    return content_type, body

【讨论】:

    【解决方案2】:

    查看at this stackoverflow question 或直接查看代码references

    urllib 通常使用application/x-www-form-urlencoded 内容类型发送数据,而您需要multipart/form-data。引用的库根据需要对数据进行编码。

    【讨论】:

      猜你喜欢
      • 2010-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-22
      • 2011-10-17
      • 1970-01-01
      • 2011-01-25
      相关资源
      最近更新 更多