Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python 3.7 urllib.request不';不遵循重定向URL_Python_Http_Urllib_Http Redirect_Http Status Code 307 - Fatal编程技术网

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

python 3.7 urllib.request不';不遵循重定向URL,python,http,urllib,http-redirect,http-status-code-307,Python,Http,Urllib,Http Redirect,Http Status Code 307,我正在使用Python3.7和urllib。 所有这些都可以正常工作,但当收到http重定向请求时,它似乎不会自动重定向(307) 这是我得到的错误: ERROR 2020-06-15 10:25:06,968 HTTP Error 307: Temporary Redirect 我必须用try-except处理它,然后手动将另一个请求发送到新位置:它工作正常,但我不喜欢它 以下是我用来执行请求的代码: req = urllib.request.Request(url)

我正在使用Python3.7和urllib。 所有这些都可以正常工作,但当收到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资源,我用一些授权信息和内容类型设置了一个标题。 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)         

可能是什么问题?

在评论部分的讨论中,您已经正确确定了重定向未自动完成的原因。具体而言,缔约国指出:

如果响应其他请求而接收到307状态代码 而不是GET或HEAD,用户代理不能自动重定向 请求,除非用户可以确认,因为这可能 更改发出请求的条件

回到问题-假设已分配
数据
,这将自动导致
获取方法
返回
发布
(根据),并且由于请求方法是
发布
,响应代码是
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
响应的一部分(由于
数据
已发布,响应中可能有一个短实体可以处理?),需要
urljoin
,因为
Location
头可能是后续资源的相对URL(或者只是缺少主机)

此外,出于兴趣(以及联系目的),这个具体问题以前被问过多次,我很惊讶他们从未得到任何答案,如下所示:


您正在访问的URL是什么?(不是你要重定向到的那个。)我在RFC 2616:10.3.8 307临时重定向上发现了这一点。如果收到307状态代码是为了响应GET或HEAD以外的请求,则除非用户能够确认,否则用户代理不得自动重定向请求,因为这可能会改变发出请求的条件。“这可能是原因吗?”卡拉布隆大声喊道。引用HTTPRequestHandler的Python文档:“一些HTTP重定向需要此模块的客户端代码执行操作。如果是这种情况,则会引发HTTPError。有关各种重定向代码的确切含义的详细信息,请参阅RFC 2616。”(我的重点)——因此,关于307,您可能是对的。在这种情况下,您的
try except
可能被视为“已由用户确认”。。。()@mrblewog是一个https url。由于我的业务政策,我不想与大家分享。不用担心——正如你在另一篇评论中所说,这可能是因为307的特殊处理。