使用requests请求含重音字符的URL触发UnicodeDecodeError问题咨询
解决Python3中Requests处理带重音字符URL的UnicodeDecodeError问题
这个问题的核心是:网站返回的重定向URL使用了Latin-1(ISO-8859-1)编码,但Requests库默认用UTF-8去解码这个地址,导致字节0xe9(对应字符é)无法被UTF-8解析,从而抛出解码错误。下面给你两个适配Python3的可行解决方案:
方案一:手动处理重定向,指定正确编码
禁用Requests的自动重定向,手动解析重定向头时用Latin-1解码,再继续请求目标地址:
import requests def request_site(url): session = requests.Session() # 关闭自动重定向,先获取初始响应 initial_resp = session.get( url, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0)'}, allow_redirects=False ) # 处理3xx重定向响应 if 300 <= initial_resp.status_code < 400: # 用Latin-1解码Location头(0xe9是Latin-1编码的é) location = initial_resp.headers['Location'].encode('latin-1').decode('utf-8') # 请求重定向后的地址 final_resp = session.get( location, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0)'} ) return final_resp return initial_resp if __name__ == '__main__': url = 'https://www.janes.com/article/87665/laad-2019-united-kingdom-s-sea-signs-mou-with-brazilian-siatt-for-tamandaré-class-corvette-torpedo-tubes' print(request_site(url))
方案二:提前对URL进行标准编码
将URL中的Unicode重音字符转换为标准的百分号编码(比如é转成%E9),让Requests可以直接正确处理:
import requests from urllib.parse import quote, urlparse, urlunparse def normalize_url(url): # 拆分URL各部分 parsed_url = urlparse(url) # 对路径部分进行UTF-8编码,转换为标准URL格式 encoded_path = quote(parsed_url.path, encoding='utf-8') # 重新组合成完整URL return urlunparse(parsed_url._replace(path=encoded_path)) def request_site(url): fixed_url = normalize_url(url) return requests.get( fixed_url, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0)'} ) if __name__ == '__main__': url = 'https://www.janes.com/article/87665/laad-2019-united-kingdom-s-sea-signs-mou-with-brazilian-siatt-for-tamandaré-class-corvette-torpedo-tubes' print(request_site(url))
方案说明
- 方案一适合网站返回非UTF-8编码重定向地址的场景,通过手动解码规避库的默认编码逻辑。
- 方案二更通用,提前将URL标准化,从根源上避免编码歧义,推荐优先使用。
内容的提问来源于stack exchange,提问作者Minions
相关产品推荐
相关产品推荐

