gpt4 book ai didi

python 3.7 urllib.request 不遵循重定向 URL

转载 作者:行者123 更新时间:2023-12-04 09:39:37 24 4
gpt4 key购买 nike

我正在使用带有 urllib 的 Python 3.7。一切正常,但当它收到 http 重定向请求 (307) 时,它似乎不会自动重定向。

这是我得到的错误:

ERROR 2020-06-15 10:25:06,968 HTTP Error 307: Temporary Redirect

我必须使用 try- except 来处理它,并手动向新位置发送另一个请求:它工作正常,但我不喜欢它。

这些是我用来执行请求的代码段:

      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 资源,我设置了一个带有一些授权信息和内容类型的 header 。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)

可能是什么问题?

最佳答案

重定向未自动完成的原因已由您在评论部分的讨论中正确识别。具体来说,RFC 2616, Section 10.3.8指出:

If the 307 status code is received in response to a request otherthan GET or HEAD, the user agent MUST NOT automatically redirect therequest unless it can be confirmed by the user, since this mightchange the conditions under which the request was issued.

回到问题 - 鉴于 data 已被分配,这会自动导致 get_method 返回 POST (根据 how this method was implemented ) ,并且由于请求方法是 POST,并且响应代码是 307,因此根据上述规范会引发 HTTPError。在 Python 的 urllib 上下文中,this specific section 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 赋值行将导致缺少“重定向”输出行。

异常处理 block 中需要注意的其他值得注意的事情,e.read() 可以用来检索服务器生成的响应正文作为 HTTP 307 的一部分> 响应(由于 data 已发布,响应中可能有一个可以处理的短实体?),并且需要 urljoin 作为 Location header 可能是后续资源的相对 URL(或者只是缺少主机)。

此外,出于兴趣(并出于链接目的),这个具体问题之前已被多次询问过,我很惊讶他们从未得到任何答案,如下:

关于python 3.7 urllib.request 不遵循重定向 URL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62384020/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com