解决UnicodeEncodeError: 'ascii' codec can't encode character

本文详细解释了在Python 3.7环境下使用urllib.request.urlopen访问URL时遇到UnicodeEncodeError错误的原因及解决方法。通过使用urllib.parse.quote函数对包含中文字符的URL进行编码,避免了ASCII编码限制导致的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

解决python中UnicodeEncodeError: ‘ascii’ codec can’t encode character ‘\uff1f’ in position 22: ordinal not in range(128)问题

问题说明:

代码环境:python3.7,PyCharm中编译。
在用 urllib.request.urlopen 访问 url 的时候,报错如下:

Traceback (most recent call last): 
File "/usr/local/lib/python3.7/urllib/request.py", line 222, in urlopen return opener.open(url, data, timeout) 
File "/usr/local/lib/python3.7/urllib/request.py", line 525, in open response = self._open(req, data) 
File "/usr/local/lib/python3.7/urllib/request.py", line 543, in _open '_open', req) File "/usr/local/lib/python3.7/urllib/request.py", line 503, in _call_chain result = func(*args) 
File "/usr/local/lib/python3.7/urllib/request.py", line 1345, in http_open return self.do_open(http.client.HTTPConnection, req) 
File "/usr/local/lib/python3.7/urllib/request.py", line 1317, in do_open encode_chunked=req.has_header('Transfer-encoding')) 
File "/usr/local/lib/python3.7/http/client.py", line 1229, in request self._send_request(method, url, body, headers, encode_chunked) 
File "/usr/local/lib/python3.7/http/client.py", line 1240, in _send_request self.putrequest(method, url, **skips) 
File "/usr/local/lib/python3.7/http/client.py", line 1107, in putrequest self._output(request.encode('ascii')) 
UnicodeEncodeError: 'ascii' codec can't encode character '\uff1f' in position 22: ordinal not in range(128)

check url后确定问题是url中有无法用ASCII码表示的中文字符,因此需要对url重新编码。

解决办法:

python3 中的urllib.parse函数可以解析url,这里可以用来重构url,具体采用其中的 quote 函数。

from urllib import request, parse
import string

f = open('./check_url.txt', 'r')
for line in f:
	# encode url
    url = parse.quote(line, safe=string.printable)
    # aviod SSL verification
    context = ssl._create_unverified_context()
    # request to open url
    # 'safe' refers to characters that can be ignored
    response = request.urlopen(url, context=context)

注意:

  1. python3.7中默认环境编码格式为 utf-8,因此在python2.7中的改变默认编码格式来解决此问题的方法不可行;
  2. parse.quote 中需要设置参数 safe ,防止url中字符完全被编码,否则会导致url中非字母的字符都变成带 ‘%’ 的转码字符,这样url就无法打开了。
  3. 参数 string.printable 的具体说明:该参数表示ASCII码第33~126号可打印字符,其中第48~57号为0~9十个阿拉伯数字;65~90号为26个大写英文字母,97~122号为26个小写英文字母,其余的是一些标点符号、运算符号等。

解法参考:https://blog.csdn.net/qq_25406563/article/details/81253347

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值