You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python3.7使用urllib.request访问URL报404及UTF-8解码错误如何解决

问题解答

1. 可在浏览器、Perl请求正常访问的URL,urllib请求返回404的原因

雅虎财经服务端配置了反爬规则,会校验请求头的User-Agent字段。urllib默认携带的UA是Python-urllib/版本号这类特征明显的爬虫标识,会被服务端直接拦截返回404。Chrome浏览器和Perl的get请求默认会携带符合正常客户端规范的UA,因此不会被拦截。
解决方法是构造请求时手动添加浏览器UA,代码示例:

# 构造带UA的请求对象
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'}
req = urllib.request.Request(url, headers=headers)
# 用请求对象发起请求
junk = urllib.request.urlopen(req, timeout=4).read()

2. 根域名请求无404但出现字节转字符串错误的原因

报错提示里的0x8b是gzip压缩格式的固定起始字节,服务端为了降低传输体积,返回了gzip压缩后的二进制内容,你直接把压缩后的内容按UTF-8解码自然会触发错误。根域名的反爬校验规则比子路径宽松,所以没有直接返回404,但默认开启了压缩传输。

3. 打印可读字节字符串junk的方法

  • 如果需要查看原始二进制的十六进制形式,直接调用print(junk.hex())即可输出标准十六进制字符串
  • 如果需要查看实际的网页文本内容,先判断响应头的压缩标识,解压后再转字符串即可,代码示例:
import gzip

resp = urllib.request.urlopen(req, timeout=4)
# 判断是否为gzip压缩内容
if resp.getheader('Content-Encoding') == 'gzip':
    junk = gzip.decompress(resp.read())
else:
    junk = resp.read()
# 此时再转字符串就不会报错
page = junk.decode('utf-8')

4. 网页编码说明

雅虎财经的网页当前依然使用UTF-8编码,你遇到的解码错误不是编码格式变更导致的,是响应内容被gzip压缩导致的。如果不确定站点编码,可以从响应头的Content-Type字段提取指定的charset参数,代码示例:

content_type = resp.getheader('Content-Type', '')
charset = 'utf-8'
if 'charset=' in content_type:
    charset = content_type.split('charset=')[1].split(';')[0].strip()
page = junk.decode(charset)

内容的提问来源于stack exchange,提问作者user1067305

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 22:15:03