如何在Python3中阻止urllib跟随HTTP重定向?
Python3下阻止urllib跟随HTTP重定向的修复方案
问题原因
你提供的Python2兼容代码在Python3中报错AttributeError: can't set attribute 'status',核心原因是Python3对urllib.request.addinfourl类做了调整,status和code属性变为只读,无法直接赋值修改。
修复方案
方案一:重写redirect_request方法(推荐)
这是Python3中更简洁且符合官方规范的写法,直接阻断重定向逻辑的触发:
import urllib.request class NoRedirectHandler(urllib.request.HTTPRedirectHandler): def redirect_request(self, req, fp, code, msg, headers, newurl): # 返回None表示不执行重定向,直接返回原始的3xx响应 return None # 安装自定义处理器 urllib.request.install_opener(urllib.request.build_opener(NoRedirectHandler())) # 使用示例 req = urllib.request.Request('http://example.com/redirect-url') res = urllib.request.urlopen(req, timeout=40) print(res.status) # 输出对应的3xx重定向状态码
方案二:适配原逻辑的修复
如果要沿用原代码的思路,可通过修改对象内部属性字典的方式绕过只读限制(不推荐长期使用,可能随Python版本迭代失效):
import urllib.request class NoRedirectHandler(urllib.request.HTTPRedirectHandler): def http_error_300(self, req, fp, code, msg, headers): data = urllib.request.addinfourl(fp, headers, req.get_full_url()) # 直接修改对象内部字典,绕过只读属性限制 data.__dict__['status'] = code data.__dict__['code'] = code return data # 为所有重定向状态码绑定处理逻辑 http_error_301 = http_error_300 http_error_302 = http_error_300 http_error_303 = http_error_300 http_error_307 = http_error_300 # 安装自定义处理器 urllib.request.install_opener(urllib.request.build_opener(NoRedirectHandler()))
内容的提问来源于stack exchange,提问作者Dizzy
相关产品推荐
相关产品推荐

