`
biansutao
  • 浏览: 53465 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Python上传文件MultipartPostHandler.py

阅读更多
#!/usr/bin/python

####
# 02/2006 Will Holcomb <wholcomb@gmail.com>
# 
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
# 
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
"""
Usage:
  Enables the use of multipart/form-data for posting forms

Inspirations:
  Upload files in python:
    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146306
  urllib2_file:
    Fabien Seisen: <fabien@seisen.org>

Example:
  import MultipartPostHandler, urllib2, cookielib

  cookies = cookielib.CookieJar()
  opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookies),
                                MultipartPostHandler.MultipartPostHandler)
  params = { "username" : "bob", "password" : "riviera",
             "file" : open("filename", "rb") }
  opener.open("http://wwww.bobsite.com/upload/", params)

Further Example:
  The main function of this file is a sample which downloads a page and
  then uploads it to the W3C validator.
"""

import urllib
import urllib2
import mimetools, mimetypes
import os, stat

class Callable:
    def __init__(self, anycallable):
        self.__call__ = anycallable

# Controls how sequences are uncoded. If true, elements may be given multiple values by
#  assigning a sequence.
doseq = 1

class MultipartPostHandler(urllib2.BaseHandler):
    handler_order = urllib2.HTTPHandler.handler_order - 10 # needs to run first

    def http_request(self, request):
        data = request.get_data()
        if data is not None and type(data) != str:
            v_files = []
            v_vars = []
            try:
                 for(key, value) in data.items():
                     if type(value) == file:
                         v_files.append((key, value))
                     else:
                         v_vars.append((key, value))
            except TypeError:
                systype, value, traceback = sys.exc_info()
                raise TypeError, "not a valid non-string sequence or mapping object", traceback

            if len(v_files) == 0:
                data = urllib.urlencode(v_vars, doseq)
            else:
                boundary, data = self.multipart_encode(v_vars, v_files)
                contenttype = 'multipart/form-data; boundary=%s' % boundary
                if(request.has_header('Content-Type')
                   and request.get_header('Content-Type').find('multipart/form-data') != 0):
                    print "Replacing %s with %s" % (request.get_header('content-type'), 'multipart/form-data')
                request.add_unredirected_header('Content-Type', contenttype)

            request.add_data(data)
        return request

    def multipart_encode(vars, files, boundary = None, buffer = None):
        if boundary is None:
            boundary = mimetools.choose_boundary()
        if buffer is None:
            buffer = ''
        for(key, value) in vars:
            buffer += '--%s\r\n' % boundary
            buffer += 'Content-Disposition: form-data; name="%s"' % key
            buffer += '\r\n\r\n' + value + '\r\n'
        for(key, fd) in files:
            file_size = os.fstat(fd.fileno())[stat.ST_SIZE]
            filename = os.path.basename(fd.name)
            contenttype = mimetypes.guess_type(filename)[0] or 'application/octet-stream'
            buffer += '--%s\r\n' % boundary
            buffer += 'Content-Disposition: form-data; name="%s"; filename="%s"\r\n' % (key, filename)
            buffer += 'Content-Type: %s\r\n' % contenttype
            # buffer += 'Content-Length: %s\r\n' % file_size
            fd.seek(0)
            buffer += '\r\n' + fd.read() + '\r\n'
        buffer += '--%s--\r\n\r\n' % boundary
        return boundary, buffer
    multipart_encode = Callable(multipart_encode)

    https_request = http_request

def main():
    import tempfile, sys

    validatorURL = "http://validator.w3.org/check"
    opener = urllib2.build_opener(MultipartPostHandler)

    def validateFile(url):
        temp = tempfile.mkstemp(suffix=".html")
        os.write(temp[0], opener.open(url).read())
        params = { "ss" : "0",            # show source
                   "doctype" : "Inline",
                   "uploaded_file" : open(temp[1], "rb") }
        print opener.open(validatorURL, params).read()
        os.remove(temp[1])

    if len(sys.argv[1:]) > 0:
        for arg in sys.argv[1:]:
            validateFile(arg)
    else:
        validateFile("http://www.google.com")

if __name__=="__main__":
    main()

 

 

上传文件的Demo: 

 

import MultipartPostHandler

 

 

  res = urllib2.urlopen('http://group.xiaonei.com/GetThread.do?id=328762314&tribeId=251102045')
  self.data = {
    'body':'闪电刀好用',\
    'theFile':open('aa.gif','rb'),\
    'ac':'c75271d1c4681d2be369ee3d390fec4f10d0e51b262586850c73c8c0bd6133052120b6c280cefe86',\
    'tribeId':'251102045',\
   }
  
  req = urllib2.Request(
             url     = 'http://upload.xiaonei.com/ReplyPost.do?thread=328762314',\
      data    = self.data)
  req.add_header('Referer', 'http://group.xiaonei.com/GetThread.do?id=328762314&tribeId=251102045')
  req.add_header('Host', 'group.xiaonei.com') 
  response = self.opener.open(req)

分享到:
评论

相关推荐

    python-base.py: 千行代码入门Python python-visual.py: 15张图入门Matplotlib

    python_spider.py: 一个很“水”的Python爬虫入门代码文件 python_weibo.py: “史上最详细”的Python模拟登录新浪微博流程 python_lda.py: 玩点高级的--带你入门Topic模型LDA(小改进+附源码) python_sqlalchemy.py...

    python3中HTMLTestRunner.py下载

    将下载后的文件放在python目录Lib文件夹下即可使用

    冒泡.py 使用python代码实现

    冒泡.py 使用python代码实现冒泡.py 使用python代码实现冒泡.py 使用python代码实现冒泡.py 使用python代码实现冒泡.py 使用python代码实现冒泡.py 使用python代码实现冒泡.py 使用python代码实现冒泡.py 使用python...

    python2.7中所用的get-pip.py文件+安装方法

    `get-pip.py`是一个Python脚本,它的主要作用是为没有预装`pip`的Python环境安装`pip`。在Python 2.7中,由于某些系统可能没有默认提供`pip`,或者`pip`版本过低,`get-pip.py`就显得非常有用。这个脚本可以下载并...

    py2pyc.py将python项目中的.py文件转为.pyc

    Compile the .py files in ...将项目文件中的所有py文件编译为pyc,另存为新的文件夹,不影响原工程 使用:python py2pyc &lt;project_dir&gt; github: https://github.com/xd404015353/py2pyc.git 有帮助的话点个星吧~

    Python文件:词云.py

    Python文件:词云.py Python文件:词云.py Python文件:词云.py

    get-pip.py

    get-pip.py: python包管理器。下载完成后,执行命令:sudo python get-pip.py完成安装。可以用此管理器进行python包的安装。

    快速排序.py python代码实现

    快速排序.py python代码实现快速排序.py python代码实现快速排序.py python代码实现快速排序.py python代码实现快速排序.py python代码实现快速排序.py python代码实现快速排序.py python代码实现快速排序.py python...

    Python3-card.py

    Python3-card.py

    堆排序6.py 使用python实现

    堆排序6.py 使用python实现堆排序6.py 使用python实现堆排序6.py 使用python实现堆排序6.py 使用python实现堆排序6.py 使用python实现堆排序6.py 使用python实现堆排序6.py 使用python实现堆排序6.py 使用python实现...

    bootchart python draw.py parsing.py samples.py

    标题中的"bootchart python draw.py parsing.py samples.py"提到了几个关键元素,它们分别是bootchart、python以及三个Python脚本文件:draw.py、parsing.py和samples.py。这些元素涉及到了Android系统的性能测试和...

    计数排序.py 使用python来实现

    计数排序.py 使用python来实现计数排序.py 使用python来实现计数排序.py 使用python来实现计数排序.py 使用python来实现计数排序.py 使用python来实现计数排序.py 使用python来实现计数排序.py 使用python来实现计数...

    基数排序.py 使用python来实现

    基数排序.py 使用python来实现基数排序.py 使用python来实现基数排序.py 使用python来实现基数排序.py 使用python来实现基数排序.py 使用python来实现基数排序.py 使用python来实现基数排序.py 使用python来实现基数...

    桶排序.py 使用python代码实现

    桶排序.py 使用python代码实现桶排序.py 使用python代码实现桶排序.py 使用python代码实现桶排序.py 使用python代码实现桶排序.py 使用python代码实现桶排序.py 使用python代码实现桶排序.py 使用python代码实现桶...

    归并排序.py 使用python代码实现

    归并排序.py 使用python代码实现归并排序.py 使用python代码实现归并排序.py 使用python代码实现归并排序.py 使用python代码实现归并排序.py 使用python代码实现归并排序.py 使用python代码实现归并排序.py 使用...

    堆排序9.py 使用python实现

    堆排序9.py 使用python实现堆排序9.py 使用python实现堆排序9.py 使用python实现堆排序9.py 使用python实现堆排序9.py 使用python实现堆排序9.py 使用python实现堆排序9.py 使用python实现堆排序9.py 使用python实现...

    安装python3-aptdaemon所需要的python文件client.py

    安装python3-aptdaemon所需要的python文件,然而,自动生成的可能在新版python中运行,需要替换。位置/usr/lib/python3/dist-packages/aptdaemon/client.py

    python_docx-0.8.10-py2.py3-none-any.whl

    估计这个安装包还只兼容python 2(python2 和python3差别还是挺大的,虽然现在python 3出来很久了,但是不少三方库还没有更新),因此需要自己找一个兼容的包:python_docx-0.8.6-py2.py3-none-any.whl。然后在...

    Python 删除.py文件

    Python 删除.py文件Python 删除.py文件Python 删除.py文件

Global site tag (gtag.js) - Google Analytics