有没有办法从Python脚本使用POST发送文件?
为了解决这个问题,我试图围绕Python标准库中旨在支持RFC 2231的各种函数.该RFC的主要目的似乎是三方面:允许在头参数中进行非ASCII编码,注意给定值的语言,并允许头参数跨越多行.该email.util库提供了几个功能来处理这方面的各个方面.据我所知,它们的工作原理如下:
decode_rfc2231 只将这样一个参数的值拆分成它的部分,如下所示:
>>> email.utils.decode_rfc2231("utf-8''T%C3%A4st.txt")
['utf-8', '', 'T%C3%A4st.txt']
Run Code Online (Sandbox Code Playgroud)
decode_params负责检测RFC2231编码的参数.它收集属于一起的部分,并将url编码的字符串解码为字节序列.然而,该字节序列被编码为latin1.并且所有值都用引号括起来.此外,第一个参数有一些特殊的处理,它仍然必须是两个元素的元组,但是这两个元素在没有修改的情况下传递给结果.
>>> email.utils.decode_params([
... (1,2),
... ("foo","bar"),
... ("name*","utf-8''T%C3%A4st.txt"),
... ("baz*0","two"),("baz*1","-part")])
[(1, 2), ('foo', '"bar"'), ('baz', '"two-part"'), ('name', ('utf-8', '', '"Täst.txt"'))]
Run Code Online (Sandbox Code Playgroud)
collapse_rfc2231_value可用于将此三重编码,语言和字节序列转换为正确的unicode字符串.然而,令我困惑的是,如果输入是这样的三倍,那么引号将被转移到输出.另一方面,如果输入是单引号字符串,则将删除这些引号.
>>> [(k, email.utils.collapse_rfc2231_value(v)) for k, v in
... email.utils.decode_params([
... (1,2),
... ("foo","bar"),
... ("name*","utf-8''T%C3%A4st.txt"),
... ("baz*0","two"),("baz*1","-part")])[1:]]
[('foo', 'bar'), ('baz', 'two-part'), ('name', '"Täst.txt"')]
Run Code Online (Sandbox Code Playgroud)
所以似乎为了使用所有这些机器,我必须再添加一个步骤来取消我遇到的任何元组的第三个元素.这是真的吗,还是我在这里错过了一些观点?我必须在源代码的帮助下弄清楚上面的很多内容,因为文档在细节上有点模糊.我无法想象这有选择性的不引用的背后可能是什么.有没有意义呢?
关于如何使用这些功能的最佳参考是什么?
到目前为止我发现的最好的是实施.在那里,过程似乎大致上面概述,但每场得到通过未加引号后,只有和崩溃他们的价值观,所有其他人返回一个元组来代替.我希望有更有用的东西.email.message.Message _unquotevaluedecode_paramsget_filenameget_boundary
我正在尝试编写一些python代码,可以在客户端创建多部分mime http请求,然后在服务器上进行适当的解释.我认为,我在客户端部分取得了成功:
from email.mime.multipart import MIMEMultipart, MIMEBase
import httplib
h1 = httplib.HTTPConnection('localhost:8080')
msg = MIMEMultipart()
fp = open('myfile.zip', 'rb')
base = MIMEBase("application", "octet-stream")
base.set_payload(fp.read())
msg.attach(base)
h1.request("POST", "http://localhost:8080/server", msg.as_string())
Run Code Online (Sandbox Code Playgroud)
唯一的问题是电子邮件库还包括Content-Type和MIME-Version标头,我不确定它们将如何与httplib包含的HTTP标头相关:
Content-Type: multipart/mixed; boundary="===============2050792481=="
MIME-Version: 1.0
--===============2050792481==
Content-Type: application/octet-stream
MIME-Version: 1.0
Run Code Online (Sandbox Code Playgroud)
这可能是我的web.py应用程序收到此请求时,我收到错误消息的原因.web.py POST处理程序:
class MultipartServer:
def POST(self, collection):
print web.input()
Run Code Online (Sandbox Code Playgroud)
抛出此错误:
Traceback (most recent call last):
File "/usr/local/lib/python2.6/dist-packages/web.py-0.34-py2.6.egg/web/application.py", line 242, in process
return self.handle()
File "/usr/local/lib/python2.6/dist-packages/web.py-0.34-py2.6.egg/web/application.py", line 233, in handle
return self._delegate(fn, self.fvars, args)
File "/usr/local/lib/python2.6/dist-packages/web.py-0.34-py2.6.egg/web/application.py", line 415, in _delegate
return handle_class(cls) …Run Code Online (Sandbox Code Playgroud) 我想发送一个带有附加文件的POST请求,尽管有些字段名称中包含Unicode字符.但是服务器没有正确接收它们,如下所示:
>>> # normal, without unicode
>>> resp = requests.post('http://httpbin.org/post', data={'snowman': 'hello'}, files={('kitten.jpg', open('kitten.jpg', 'rb'))}).json()['form']
>>> resp
{u'snowman': u'hello'}
>>>
>>> # with unicode, see that the name has become 'null'
>>> resp = requests.post('http://httpbin.org/post', data={'?': 'hello'}, files={('kitten.jpg', open('kitten.jpg', 'rb'))}).json()['form']
>>> resp
{u'null': u'hello'}
>>>
>>> # it works without the image
>>> resp = requests.post('http://httpbin.org/post', data={'?': 'hello'}).json()['form']
>>> resp
{u'\u2603': u'hello'}
Run Code Online (Sandbox Code Playgroud)
我该如何解决这个问题?