我在与urllib一起使用Python3.7。所有的工作都很好,但是当它得到一个http重定向请求(307)时,它似乎不会以其他方式重定向。
这是我得到的错误:
ERROR 2020-06-15 10:25:06,968 HTTP Error 307: Temporary Redirect
我不得不尝试-除了手动发送另一个请求到新的位置:它工作良好,但我不喜欢它。
下面是我用来执行请求的代码:
req = urllib.request.Request(url)
req.add_header('Authorization', auth)
req.add_header('Content-Type','application/json; charset=utf-8')
req.data=jdati
self.logger.debug(req.headers)
self.logger.info(req.data)
resp = urllib.request.urlopen(req)
url是https资源,我用一些Authhorization和内容类型设置了一个标题。req.data是一个JSON
从urllib文档中,我了解重定向是由库本身真实地执行的,但它对我不起作用。它总是引发一个http 307错误,并且不遵循重定向URL。我还尝试使用(默认重定向处理程序),但结果相同
opener = urllib.request.build_opener(urllib.request.HTTPRedirectHandler)
req = urllib.request.Request(url)
req.add_header('Authorization', auth)
req.add_header('Content-Type','application/json; charset=utf-8')
req.data=jdati
resp = opener.open(req)
有什么问题吗?
发布于 2020-06-15 09:25:25
重定向没有自动完成的原因已经在注释部分的讨论中被您正确地识别了。具体而言,RFC 2616,10.3.8节指出:
如果响应GET或HEAD以外的请求而接收307状态代码,则用户代理不能自动重定向请求,除非它可以由用户确认,因为这可能改变发出请求的条件。
回到问题--考虑到已经分配了data
,这将自动导致get_method
返回POST
(按照该方法是如何实现的),并且由于请求方法是POST
,响应代码是307
,因此将按照上述规范引发HTTPError
。在Python的urllib
上下文中,urllib.request
模块的这一特定部分引发异常。
对于实验,请尝试以下代码:
import urllib.request
import urllib.parse
url = 'http://httpbin.org/status/307'
req = urllib.request.Request(url)
req.data = b'hello' # comment out to not trigger manual redirect handling
try:
resp = urllib.request.urlopen(req)
except urllib.error.HTTPError as e:
if e.status != 307:
raise # not a status code that can be handled here
redirected_url = urllib.parse.urljoin(url, e.headers['Location'])
resp = urllib.request.urlopen(redirected_url)
print('Redirected -> %s' % redirected_url) # the original redirected url
print('Response URL -> %s ' % resp.url) # the final url
按原样运行代码可能会产生以下结果
Redirected -> http://httpbin.org/redirect/1
Response URL -> http://httpbin.org/get
注意,对get
的后续重定向是自动完成的,因为随后的请求是GET
请求。注释掉req.data
赋值行将导致缺少“重定向”输出行。
在异常处理块中要注意的其他值得注意的事情是,可以执行e.read()
来检索服务器作为HTTP 307
响应的一部分而产生的响应体(由于发布了data
,响应中可能有一个短的实体可被处理?),并且需要urljoin
,因为Location
头可能是与后续资源的相对URL (或主机丢失)。
此外,作为一个令人感兴趣的问题(为了联系的目的),这一具体问题以前曾多次被问过,我感到相当惊讶的是,他们从未得到任何答案,如下所示:
https://stackoverflow.com/questions/62384020
复制相似问题