【问题标题】:Is it really possible to POST files with python?真的可以用python发布文件吗?
【发布时间】:2011-04-25 16:06:21
【问题描述】:

所以我连续第二天为此苦苦挣扎,但仍然一无所获。在互联网上找到了一些解决方案,但在尝试使用 POST 发送文件时仍然出现“内部服务器错误”。想法如下:我将在 python 的 shell 中打开的文件发送到我的服务器上的 django 函数,该函数将在那里读取并存储文件。我试过 urllib、urllib2(有和没有poster 模块)、httplib 和Multipart 方法。这是我尝试过的所有结果的完整列表:

#Variables
In [35]: url = "http://www.address"
In [36]: values = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
In [37]: dataurllib = urllib.urlencode(values)
In [39]: dataposterlib, dataheaders = multipart_encode(values)
In [40]: dataposterlib
Out[40]: <generator object yielder at 0x15a0410>
In [41]: headers
{'Content-Length': 491,
 'Content-Type': 'multipart/form-data; boundary=13936c2ddba0441eab9c3f4133a4009e'}
In [43]: f = open("winter.jpg", "rb")
In [45]: filegen, fileheaders = multipart_encode({"file": f})
In [46]: filegen
Out[46]: <generator object yielder at 0xc5b3c0>
In [47]: fileheaders
Out[47]:
{'Content-Length': 39876,
 'Content-Type': 'multipart/form-data; boundary=0aa7a1b68d714440be06e166080925ec'}


#Working:

1. urllib.urlopen("http://www.address", data=urllib.urlencode({"key": "value"}))
2. urllib.urlopen(url, data=urllib.urlencode({"key": "value"}))
3. urllib.urlopen(url, data=urlib.urlencode(values))
4. urllib.urlopen(url, urlib.urlencode(values))
5. urllib.urlopen(url, data=dataurllib)
6. urllib.urlopen(url, dataurllib)
7. urllib.urlopen(url, data=urllib.urlencode({"file": f})) : works, but doesnt send file

8.  import cookielib
    from utils.multipart import MultipartPostHandler
    cookies = cookielib.CookieJar()
    opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookies), MultipartPostHandler)
    params = { "username": "bob", "password": "riviera", "file": f }
    opener.open(url, params)

#Not working: 

4. u = urllib.urlopen(url, "string")
5. u = urllib.urlopen(url, data="string")
7. u = urllib2.urlopen(url, data=urllib.urlencode(values)) : Error 500 but sends data
6. u = urllib2.urlopen("http://www.fandrive.yum.pl/event/upload/", data=urllib.urlencode({"key": "value"})) : Error 500 but sends data
7. u = urllib2.urlopen(url, data=urllib.urlencode({"key": "value"})) : Error 500 but sends data
8. u = urllib2.urlopen(url, data=dataurllib) : Error 500 but sends data
9. u = urllib2.urlopen(url, dataurllib) : Error 500 but sends data
10. In [31]: req = urllib2.Request(url, f, fileheaders)
    urllib2.urlopen(req)                                : Error 500
11. req = urllib2.Request(url, filegen, fileheaders)
    urllib2.urlopen(req)                                : Error 500, very seldomly sends data
12. req = urllib2.Request(url, dataurllib)
    urllib2.urlopen(req)                                : Error 500, sends data

我发现有人有同样的问题,所以我借用了他的 django 函数(基于this post

def upload(request):
    logging.debug("GO")
    for key, file in request.FILES.items():
        path = '/path/'+ file.name
        logging.debug(path)
        dest = open(path.encode('utf-8'), 'wb+')
        logging.debug(dest)
        if file.multiple_chunks:
            loggin.debug("big")
            for c in file.chunks():
                dest.write(c)
        else:
            logging.dobug("small")
            dest.write(file.read())
        dest.close()
    destination = path + 'test.txt'
    logging.debug(destination)
    file = open(destination, "a")
    file.write("file \n")
    file.close        
    return 0

我注意到,即使我的函数运行,发送的文件也没有保存,destination... 之后的代码也被跳过。就像在它到达这个地方之前会有超时一样。 Wireshark 显示正在发送 POST 请求,但服务器总是给出 500 错误。这是怎么回事?我已经尝试了与我的 2 台服务器以及从本地计算机发送的几种组合,但仍然没有。我在这里想念什么?我使用与互联网上其他人相同的代码。即使 urllib 可以工作,即使是内置的 urllib2 模块也总是报错。

编辑

我已将服务器更改为另一台,最后我有一些可靠的错误日志(接收方):

[Sat Oct 16 20:40:46 2010] [error] [client IP] mod_python (pid=24773, interpreter='host', phase='PythonHandler', handler='django.core.handlers.modpython'): Application error
[Sat Oct 16 20:40:46 2010] [error] [client IP] ServerName: 'xxx'
[Sat Oct 16 20:40:46 2010] [error] [client IP] DocumentRoot: 'path'
[Sat Oct 16 20:40:46 2010] [error] [client IP] URI: '/error/internalServerError.html'
[Sat Oct 16 20:40:46 2010] [error] [client IP] Location: None
[Sat Oct 16 20:40:46 2010] [error] [client IP] Directory: None
[Sat Oct 16 20:40:46 2010] [error] [client IP] Filename: 'path/error/internalServerError.html'
[Sat Oct 16 20:40:46 2010] [error] [client IP] PathInfo: ''
[Sat Oct 16 20:40:46 2010] [error] [client IP] Traceback (most recent call last):
[Sat Oct 16 20:40:46 2010] [error] [client IP]   File "/usr/lib/python2.5/site-packages/mod_python/importer.py", line 1537, in HandlerDispatch\n    default=default_handler, arg=req, silent=hlist.silent)
[Sat Oct 16 20:40:46 2010] [error] [client IP]   File "/usr/lib/python2.5/site-packages/mod_python/importer.py", line 1229, in _process_target\n    result = _execute_target(config, req, object, arg)
[Sat Oct 16 20:40:46 2010] [error] [client IP]   File "/usr/lib/python2.5/site-packages/mod_python/importer.py", line 1128, in _execute_target\n    result = object(arg)
[Sat Oct 16 20:40:46 2010] [error] [client IP]   File "/usr/lib/python2.5/site-packages/django/core/handlers/modpython.py", line 228, in handler\n    return ModPythonHandler()(req)
[Sat Oct 16 20:40:46 2010] [error] [client IP]   File "/usr/lib/python2.5/site-packages/django/core/handlers/modpython.py", line 220, in __call__\n    req.write(chunk)
[Sat Oct 16 20:40:46 2010] [error] [client IP] IOError: Write failed, client closed connection.
[Sat Oct 16 20:40:46 2010] [error] [client IP] python_handler: Dispatch() returned non-integer.

【问题讨论】:

  • 对我来说奇怪的是,对于网络上的不同问题,错误的回溯总是显示相同的代码片段(来自 urllib2)。
  • 因为问题出在接收方。它无法写入本地文件系统。

标签: python post file-upload request


【解决方案1】:

主要编辑:

非常抱歉,我给了你错误的代码。我使用的工作代码基于此: http://code.activestate.com/recipes/146306-http-client-to-post-using-multipartform-data/ 所以我不会在这里重复它并声称它是我的。

由于您的评论,我阅读了RFC1867 并意识到我给了您错误的代码(我也使用这个,如果您控制双方,它很方便)。

您的错误日志显示IOError: Write failed, client closed connection.,我想这意味着服务器要么尝试将一些数据(文件?)写入它不应该写入的地方,要么我没有文件系统权限来写。您应该检查它在哪里,并为服务器运行的用户寻找写权限。

【讨论】:

  • 我之前已经尝试过使用 httplib:/ 我该如何处理这个错误?它只是向我展示了示例代码,每个人在收到 500 错误时都会得到。服务器日志显示“脚本头过早结束:”但不完全是在我发送请求的时候,所以我不确定它是否以任何方式连接。
  • 我在接收方一无所获。该死的,我完全浪费了 2 天没有任何结果。
  • 如果接收端抛出 HTTP 500 并且没有记录任何内容,那么您有严重的问题需要解决。
  • 但是如果我从本地主机发送时得到它,我应该在我的服务器上查找源吗?
  • HTTP 500 来自您发布到的服务器。如果它位于您的本地主机上,请看那里。然而,它与您发布的 where 无关。
猜你喜欢
  • 1970-01-01
  • 2020-12-16
  • 1970-01-01
  • 2017-12-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-01
  • 1970-01-01
  • 2021-08-14
相关资源
最近更新 更多