使用urllib2上传文件

时间:2010-12-21 06:10:55

标签: python file-upload urllib2

我是python的新手,我正在编写一个代码来使用urllib2上传文件,但我无法使其正常工作。

以下是代码:

class Get(object):
    handlers = list()
    def __init__(self,url):
        self.url = url
        self.request = urllib2.Request(url)
        self.request.add_header('User-Agent',"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13")

    def auth(self,username,password):
        pass_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
        pass_mgr.add_password(None, self.url, username, password)
        handler = urllib2.HTTPBasicAuthHandler(pass_mgr)
        self._add_handler(handler)

    def perform(self):
        try:
            opener = self._opener()
            res = opener.open(self.request)
            to_return = {
                'code': res.code,
                'contents': res.read(),
                'url': res.geturl(),
                'headers': dict(res.info())
            }
        except urllib2.URLError as e:
            if hasattr(e, 'reason'):
                print 'Error accessing the server.'
                print 'Reason: ', e.reason
            elif hasattr(e, 'code'):
                print 'The server couldn\'t fulfill the request.'
                print e
        else:
            return to_return

    def _add_handler(self,handler):
        self.handlers.append(handler)

    def _opener(self):
        return urllib2.build_opener(*self.handlers)

class Multipart(object):
    def __init__(self,url):
        super(Multipart,self).__init__(url)
        self.data = list()

    def perform(self):
        b = choose_boundary()

        tmp = "".join(map(lambda x: "--%s \r\n %s" % (b,x), self.data )) 
        tmp += "--%s--\r\n" % b
        self.request.add_data(tmp)
        content_type = 'multipart/form-data; boundary=%s' % b
        self.request.add_unredirected_header('Content-Type', content_type)
        #self.request.add_header("Content-Type","multipart/form-data, boundary=%s" % b)
        return super(HTTP.Multipart,self).perform()

    def set_data(self,data,file = None):
        for i in data:
            if file:
                self.data.append(self._encode_file(i,**data[i]))
            else:
                self.data.append(self._encode_text(i,data[i]))

    def _encode_text(self,key,value):
        return "Content-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n" % (key, value)

    def _encode_file(self,key,path,filename=None,mime_type=None):
        if not exists(path):
            raise RuntimeError('%s not found' % path)

        fname = filename or basename(path)
        mime = mime_type or guess_type(path)[0] or 'application/octet-stream'
        size = getsize(path)
        content = ""
        with open(path,'rb') as fobj:
            content = fobj.read(size)

        converted_text = "Content-Disposition: form-data; name=\"%s\";     filename=\"%s\"\r\n" % (key,fname)
        converted_text += "Content-Transfer-Encoding: binary\r\n"
        converted_text += "Content-Type: %s \r\n" % mime
        converted_text += "Content-Length: %s \r\n" % size
        converted_text += "\r\n %s \r\n" % content

        return converted_text

1 个答案:

答案 0 :(得分:2)

感谢 MultipartPostHandler 现在一切正常。

class Post(Get): # inherits the Get class above
    def __init__(self,url,data,multipart=False):
        super(HTTP.Post,self).__init__(url)
        if multipart:
            from MultipartPostHandler import MultipartPostHandler
            self._add_handler(MultipartPostHandler)
            self.request.add_data(data)
        else:
            self.request.add_data(urlencode(data))