解析指定RSS链接触发UnicodeEncodeError,chardet检测为ASCII编码求解决
问题解析与解决
问题描述
解析RSS链接https://tre.tbe.taleo.net/tre01/ats/servlet/Rss?org=arobpers2&cws=42时,触发UnicodeEncodeError: 'utf-8' codec can't encode character '\ud83c' in position 0: surrogates not allowed错误。虽然chardet检测显示文本为ASCII编码,但实际响应中存在无效的UTF-16代理对字符(\ud83c是未配对的高代理字符,不属于合法Unicode),导致feedparser处理失败。
原因分析
- requests的
r.text会自动尝试解码响应字节,但如果服务器返回的编码标识不准确,可能错误解码出无效的代理字符。 - chardet检测的是
r.text.encode()的结果(即把已解码的Unicode字符串再转成UTF-8字节),由于内容主体是ASCII,因此误判为ASCII编码,无法识别隐藏的无效代理字符。
解决方法
方法1:直接传入原始字节流给feedparser解析
feedparser自带更完善的编码自动检测逻辑,跳过requests的手动解码,直接传入原始响应字节:
import feedparser import requests url = "https://tre.tbe.taleo.net/tre01/ats/servlet/Rss?org=arobpers2&cws=42" r = requests.get(url) feed = feedparser.parse(r.content) # 用r.content代替r.text
方法2:清理无效代理字符
如果必须使用r.text,可先过滤掉未配对的代理字符,再传入feedparser:
import re import feedparser import requests def remove_surrogates(text): # 匹配并移除未配对的UTF-16代理字符 return re.sub(r'[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]', '', text) url = "https://tre.tbe.taleo.net/tre01/ats/servlet/Rss?org=arobpers2&cws=42" r = requests.get(url) cleaned_text = remove_surrogates(r.text) feed = feedparser.parse(cleaned_text)
方法3:手动指定正确编码解码
若能确定服务器返回的实际编码(比如UTF-8),手动指定编码避免requests自动解码出错:
import feedparser import requests url = "https://tre.tbe.taleo.net/tre01/ats/servlet/Rss?org=arobpers2&cws=42" r = requests.get(url) r.encoding = 'utf-8' # 手动指定编码 feed = feedparser.parse(r.text)
内容的提问来源于stack exchange,提问作者Asher Ross
相关产品推荐
相关产品推荐

