通过Pyside / PyQt中的http帖子上传文件

时间:2014-01-16 09:37:39

标签: python qt http pyqt pyside

我正在尝试将文件和其他POST变量发送到客户服务器上的xfilesharing脚本(位于perl中)。

Google上没有很好的资源,我发现的代码示例不起作用。(实际上它们是用c ++编写的,我无法让它们工作)

服务器正在使用Apache进行网络服务器

之前我问了一个问题,我得到了一个很好的答案,所以我在这里使用uploader,代码不适用于通过http post上传文件

所以任何人都可以首先告诉我通过HTTP帖子上传文件需要做什么然后如果你能给我一个样本(在本地主机上传的简单代码就足够了,我只想要看看如何做到这一点以及如何上传工作)

1 个答案:

答案 0 :(得分:5)

这个问题看起来非常困难。确实没有关于这个主题的完整例子。

PyQt的

在PyQt4中,我设法运行QHttpMultiPart documentation中提供的示例。适应的Python版本(需要Qt 4.8):

from PyQt4 import QtGui, QtCore, QtNetwork
import sys
import time

def finished(reply):
  print "Finished: ", reply.readAll()
  app.quit()

def construct_multipart(data, files):
  multiPart = QtNetwork.QHttpMultiPart(QtNetwork.QHttpMultiPart.FormDataType)
  for key, value in data.items():
    textPart = QtNetwork.QHttpPart()
    textPart.setHeader(QtNetwork.QNetworkRequest.ContentDispositionHeader,
      "form-data; name=\"%s\"" % key)
    textPart.setBody(value)
    multiPart.append(textPart)

  for key, file in files.items():
    imagePart = QtNetwork.QHttpPart()
    #imagePart.setHeader(QNetworkRequest::ContentTypeHeader, ...);
    fileName = QtCore.QFileInfo(file.fileName()).fileName()
    imagePart.setHeader(QtNetwork.QNetworkRequest.ContentDispositionHeader,
      "form-data; name=\"%s\"; filename=\"%s\"" % (key, fileName))
    imagePart.setBodyDevice(file);
    multiPart.append(imagePart)
  return multiPart

app = QtGui.QApplication(sys.argv)
file1 = QtCore.QFile('/tmp/1.txt')
file1.open(QtCore.QFile.ReadOnly)
url = QtCore.QUrl('http://localhost:3000/qwertytest1');
data = { 'text1': 'test1', 'text2': 'test2' }
files = {'file1': file1 }
multipart = construct_multipart(data, files)
request_qt = QtNetwork.QNetworkRequest(url)
request_qt.setHeader(QtNetwork.QNetworkRequest.ContentTypeHeader,
  'multipart/form-data; boundary=%s' % multipart.boundary())
manager = QtNetwork.QNetworkAccessManager()
manager.finished.connect(finished)
request = manager.post(request_qt, multipart)

sys.exit(app.exec_())

PySide

PySide实现缺少QHttpMultiPart。唯一的方法是手动构建发布数据内容。幸运的是,Python有自己的库来创建多部分HTTP请求。这是我写的:

import sys
from PySide import QtCore, QtGui, QtNetwork
import requests

def finished(reply):
  print "Finished: ", reply.readAll()
  app.quit()

app = QtGui.QApplication(sys.argv)
url = 'http://localhost:3000/qwertytest1'
data = { 'text1': 'test1', 'text2': 'test2' }
files = {'file1': open('/tmp/1.txt') }
request = requests.Request('POST', url, data=data, files=files).prepare()
request_qt = QtNetwork.QNetworkRequest(url)
for header, value in request.headers.items():
  request_qt.setRawHeader(header, value)
manager = QtNetwork.QNetworkAccessManager()
manager.finished.connect(finished)
request = manager.post(request_qt, request.body)

sys.exit(app.exec_())

请注意,此方法会加载内存中的所有文件内容。如果你正在处理大文件,这是不可接受的。 python-requests模块本身支持动态发送大文件,但是没有办法在Qt中使用这个功能。如果是这种情况,你可以在没有Qt的情况下使用python-requests。