我花了几天时间试图找出如何在Python中将图像发布到CloudApp,使用请求访问{a2}。我可以使用pycloudapp,它使用Poster来完成,但是我想学习如何处理请求。在
我一直在尝试使用InspectB.in来比较我的脚本和pycloudapp发布的内容,试图找出差异。似乎不多,但显然存在的少数是重要的。对于我当前的代码,我得到了一个服务器端错误(500),这是令人沮丧的。因为基于海报的代码可以工作,所以我希望找到一种方法让请求也能工作,尽管我认为这可能不可行。在
CloudApp使用amazonweb存储,我知道AWS必须最后使用“file”参数。到目前为止,我已经尝试过几种使用data = collections.OrderedDict(sorted(upload_values)); data['file'] = open(last_pic, 'rb')
而不是使用单独的data
和{files
字典,有没有文件名。在
这是我的代码:
#!/usr/bin/env python
import requests
import os
last_pic = '/.../image.jpg'
USER = 'email@email.com'
PASS = 'mypass'
AUTH_URL = 'http://my.cl.ly'
API_URL = 'http://my.cl.ly/items/new'
s = requests.Session()
s.auth = requests.auth.HTTPDigestAuth(USER, PASS)
s.headers.update({'Accept': 'application/json'})
upload_request = s.get(API_URL)
upload_values = upload_request.json()['params']
filename = os.path.basename(last_pic)
upload_values['key'] = upload_values['key'].replace(r'${filename}', filename)
files = {'file': open(last_pic, 'rb')}
stuff = requests.post(upload_request.json()['url'], data=upload_values, files=files)
print(stuff.text)
根据检查B.in,工作(pycloudapp)帖子和我的帖子之间的唯一区别是:
pycloudapp post主体中的每个参数都有Content-Type: text/plain; charset=utf-8
,但在我的代码中没有。例如:
与我的对比:
--b1892e959d124887a61143dd2b468579
Content-Disposition: form-data; name="acl"
public-read
文件数据不同。在
pycloudapp:
--d5e0c013a6de4105b07ac844eea4da6e
Content-Disposition: form-data; name="file"
Content-Type: text/plain; charset=utf-8
����JFIFHH���ICC_PROFILE�applmntrRGB XYZ �...
与我的对比:
--b1892e959d124887a61143dd2b468579
Content-Disposition: form-data; name="file"; filename="20130608-ScreenShot-180.jpg"
Content-Type: image/jpeg
����JFIFHH���ICC_PROFILE�applmntrRGB XYZ �...
标题基本相同,除了:
pycloudapp:
Accept: application/json
Accept-Encoding: identity
我的:
Accept: */*
Accept-Encoding: gzip, deflate, compress
具体来说,这两个都成功注册为Content-Type: multipart/form-data
考虑到accept头可能是重要的区别,我尝试添加headers = {'accept': 'application/json', 'content-type': 'multipart/form-data'}
(以及这两个单独的),但没有成功。不幸的是,如果我修改头,它会覆盖所有的头并丢失多部分编码。在
我还想知道我的文章中的文件Content-Type: image/jpeg
与工作帖子中的Content-Type: text/plain; charset=utf-8
是否是问题所在。在
很抱歉这么长的帖子,这已经把我逼疯了,谢谢你能提供的任何帮助。在
几天后,我终于解决了这个(简单的)问题。cloudappapi需要对Amazon响应中的“Location”头发出“GET”请求。在
Pycloudapp工作正常,因为它使用
return json.load(self.upload_auth_opener.open(request))
正确验证了GET响应。在我不知道为什么我能够在没有任何身份验证的情况下使用Postman正确地发布,不管怎么说,它是正确地跟随GET而没有凭据,即使cloudappapi指定遵循重定向requires authentication。在
我无法正确跟踪请求的重定向,因为我发布的是未经验证的值(如果我继续使用s.post执行Session(),则auth头会抛出错误,因为Amazon并不期望这些值),因此随后的GET也是未经验证的。这场痛苦的一个非常令人困惑的部分是,发布的图片在我的CloudApp帐户中显示的是而不是。然而,我后来发现,我可以手动将亚马逊的回复“位置”粘贴到一个浏览器窗口中,突然,发布的图片出现在我的账户中。这使我意识到POST是不够的;需要一个经过身份验证的GET来完成这个过程。在
然后我发现我没有从
requests.post.headers
得到任何帮助。花了几分钟时间,才发现它是用重定向的头响应的(它跟踪的GET中的500个错误),而不是POST。一旦我添加了allow_redirects=False
,我就可以正确地访问Amazon响应的“Location”头。我刚刚把这个头反馈到我的已验证会话()中,它终于起作用了。在另一个对这个过程很有帮助的东西是this SO thread,它教会了我logging with Requests。在
希望这个解释有道理,对其他人有帮助。这几天我确实学到了很多东西。我的代码可能还需要改进,我想用urllib.quote_plus但我今天要等8次上传了。在
我的当前代码:
相关问题 更多 >
编程相关推荐