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

2024-02-02

我正在使用带有 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 资源,我设置了一个带有一些授权信息和内容类型的标头。 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,第 10.3.8 节 https://www.rfc-editor.org/rfc/rfc2616#section-10.3.8指出:

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

回到问题 - 鉴于data已被分配,这会自动导致get_method返回POST(按照这个方法是如何实现的 https://github.com/python/cpython/blob/v3.8.3/Lib/urllib/request.py#L388),因为请求方法是POST,响应代码为307, an HTTPError而是按照上述规范提出。在 Python 的上下文中urllib, 这个特定部分 https://github.com/python/cpython/blob/v3.8.3/Lib/urllib/request.py#L670 of the 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需要作为Locationheader 可以是后续资源的相对 URL(或者只是缺少主机)。

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

  • 如何使用 urllib2 处理从 http 到 https 的 307 重定向 https://stackoverflow.com/questions/44662147/how-to-handle-307-redirection-using-urllib2-from-http-to-https
  • HTTP 错误 307:Python3 中的临时重定向 - INTRANET https://stackoverflow.com/questions/57304591/http-error-307-temporary-redirect-in-python3-intranet
  • HTTP 错误 307 - python 脚本中的临时重定向 https://stackoverflow.com/questions/38669984/http-error-307-temporary-redirect-in-python-script
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python 3.7 urllib.request 不遵循重定向 URL 的相关文章

随机推荐

  • 如何检查客户端网络/防火墙上的端口是否打开?

    最后通过 jQuery AJAX 和 JSONP 的 超时 属性解决了这个问题 看我自己的回答 请参阅更新的部分 我也尝试过使用小程序 如果您能提供小程序实现的解决方案 我们将毫不犹豫地接受您的答案 我正在使用基于 Java 的 Web 应
  • 如何在 React Native 中添加按钮网格样式?

    我最近将手放在了 React Native 上 并尝试将按钮动态添加到视图中 我想要一个像这样的结构 在引导程序中我会添加一个带有 col md 4 的类 A A A A A A A A A A A A 我已经可以添加按钮 但它们总是出现在
  • .NET / C# 的线性编程库 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我需要求解欠定线性方程组和约束 然后找到最小化成本函数的特定解决方案 这需要通过在 NET 和 Mon
  • 如何在谷歌地图目标c上旋转自定义标记图像

    目前我正在开发一个像 Uber iOS 应用程序这样的应用程序 我已经集成了 Google Maps SDK 并且还显示了用户当前位置的自定义图像 目前我正在从服务器获取一些驾驶员当前位置详细信息 例如 100 个驾驶员 我保存在一个NSA
  • 我不清楚应用函子评估

    我目前正在阅读 Learn a Haskell for Great Good 并且我偶然发现了对某个代码块的评估的解释 我已经阅读了几次解释 并且开始怀疑作者是否理解这段代码的作用 ghci gt lt gt 3 lt gt 100 5 5
  • Android SearchView 过滤器 ListView

    我已在 SherlockAction Bar 中的 SearchView 中实现了搜索过滤器 当我输入 m 时 我想在下面的列表视图中显示过滤结果 该结果仅以 M 开头 依此类推 但现在它显示随机结果 public boolean onQu
  • matplotlib 需要 pyparsing

    我正在尝试使用 matplotlib 绘制一些数据 导入库时 出现错误 ImportError matplotlib requires pyparsing 我使用安装了 pyparsingeasy install pyparsing 但错误
  • 从 Access 数据库获取数据的正确方法

    我对如何从访问数据库获取数据有点困惑 首先将其收集在列表中然后从列表中获取这些数据是否正确 或者直接将其获取到数据库中是否可以 我的代码工作得很好 但我想知道是否有更好的方法来做到这一点 private void button3 Click
  • 为什么我不应该使用 Process.GetCurrentProcess().Kill() 退出我的 WinForm 应用程序?

    现在 当用户想要退出我的应用程序时 我必须执行一些操作 即与服务器断开连接 保存用户数据 然后执行以下操作 使用布尔值退出所有主循环 中止仍在运行的线程 通常是我的服务器轮询线程 请调用Application Exit 这需要几秒钟才能退出
  • 点击显示更多 - 也许是 JS?

    我不确定使用什么语言或如何执行此操作 但我希望在页面上有一个单词 当单击时 它会在下面显示更多内容 再按一下 那东西又会隐藏起来吗 有任何想法吗 基本上 您需要操纵display要隐藏 显示的元素的 CSS 属性 span Show spa
  • 如何使用Spring响应式增量进度更新来逐一处理每个产品?

    我需要有关 Spring Reactive 的帮助 其中休息调用会发布 Json 对象列表 并且 Spring Boot 服务器应一一发送处理事件 让我用一个例子来简单解释一下 假设前端 UI 中有 20 个产品 用户选择所有要处理的产品
  • PHP:如何使用 HTTP-Basic 身份验证发出 GET 请求

    我想从此端点获取交易状态 https api sandbox midtrans com v2 orderid status 但它需要一个基本的身份验证 当我将其发布到 URL 上时 我得到的结果是 status code 401 statu
  • ASIHTTPRequest 构建/链接错误

    void getFacebookProfile NSString urlString NSString stringWithFormat https graph facebook com me access token accessToke
  • 在 shell 脚本中使用 psql 创建数据库将用户名作为数据库名称

    以下是我用来在 shell 脚本中创建数据库的命令 psql v ON ERROR STOP 1 username POSTGRES USER c CREATE DATABASE database 它抛出错误 FATAL database
  • powershell 在输出中将换行符放在不适当的位置

    我有一个 PowerShell 脚本 但某些输出在继续下一行之前会在任意点被剪切 这非常烦人 例如 我可以使用Write Host只要我想要 该行就会继续 注意 在 Team City 中运行 并且 Team City 添加了一些前缀信息
  • python matplotlib 标签/标题错误字符

    这是部分交叉帖子这个问题 https stackoverflow com questions 14712292 python matplotlib axis label subscript based on loop counter 这是我
  • 创建 tf.keras 回调以保存 tf 2.0 训练期间每批的模型预测和目标

    在tensorflow 2中 不再支持获取和分配 按照 中提供的答案 可以在自定义 keras 回调中访问 tf 1 x 中的批处理结果https stackoverflow com a 47081613 9949099 https sta
  • 如何摆脱波动性?

    如何摆脱波动性 我应该使用哪种 C 风格转换 Use const cast 例如 volatile sample pvs new sample sample ps const cast
  • 限制CursorLoader中的查询

    我正在尝试通过 CursorLoader 从 sqlite db 查询数据 当我浏览 Android 开发者网站中的文档时 我找不到限制查询 CursorLoader Context context Uri uri String proje
  • python 3.7 urllib.request 不遵循重定向 URL

    我正在使用带有 urllib 的 Python 3 7 一切工作正常 但当它收到 http 重定向请求 307 时 它似乎没有自动重定向 这是我得到的错误 ERROR 2020 06 15 10 25 06 968 HTTP Error 3