Python2 urllib2代码迁移至Python3.9 urllib遇错误求助
Python2 urllib2 代码转 Python3.9 urllib 完整解决方案
下面是适配Python3.9的可运行代码,解决了你遇到的类型错误和500服务器错误问题:
def linux_inventoryAWS(self): servers = [] # 用urllib.parse处理表单编码,和Python2逻辑一致 data = urllib.parse.urlencode({ 'header':'yes', 'query':'select distinct lower(a.name), a.service_level from view_device_v1 a LEFT OUTER JOIN view_device_custom_fields_flat_v1 b ON (a.device_pk=b.device_fk) LEFT JOIN view_objectcategory_v1 cat ON a.objectcategory_fk=cat.objectcategory_pk where a.os_name ~ \'Linux\' and a.in_service=\'t\' and a.type=\'virtual\' and (virtual_subtype=\'Amazon EC2 Instance\' or virtual_subtype=\'Citrix/Xen\' or virtual_subtype=\'Xen\') and (excludefromautmninventory is null or excludefromautmninventory != \'Yes\') order by a.service_level asc' }) # 转字节类型,满足Python3 POST数据要求 data_bytes = data.encode('utf-8') # Basic Auth处理:先转字节再编码,最后解码为字符串 credentials = f"{self.d42_user}:{self.d42_pwd}" credentials_bytes = credentials.encode('utf-8') base64string = base64.b64encode(credentials_bytes).decode('ascii') url = f"{self.d42_url}/services/data/v1.0/query/" # 直接将data传入Request构造器,替代Python2的add_data方法 request = urllib.request.Request(url, data=data_bytes) request.add_header("Authorization", f"Basic {base64string}") # SSL逻辑和原代码一致 ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE # 读取响应时转字符串,解决字节/字符串类型不匹配 with urllib.request.urlopen(request, context=ctx) as result: for line in result: servers.append(line.decode('utf-8').strip('\n')) servers.pop(0) serversAsString = ",".join(servers) return servers
关键修改说明(对应你遇到的错误):
- POST数据转字节:Python3要求POST数据必须是字节类型,
urllib.parse.urlencode返回的是字符串,所以用encode('utf-8')转换,解决TypeError: POST data should be bytes...错误。 - Basic Auth编码调整:
base64.b64encode在Python3中只接受字节输入,先把用户名密码转字节,编码后再解码为ASCII字符串,避免字节与字符串拼接的类型错误。 - 请求数据传递方式:Python3中直接把data作为
Request构造参数传入,替代Python2弃用的add_data方法,这是导致500错误的核心原因——原方法弃用后参数传递错误,服务器无法解析请求。 - 响应内容转字符串:
urlopen返回的行是字节类型,用decode('utf-8')转成字符串后再处理换行符,解决TypeError: a bytes-like object is required, not 'str'错误。 - with语句管理响应:自动关闭响应对象,比手动
close更稳妥,避免资源泄漏。
内容的提问来源于stack exchange,提问作者Beam Davis
相关产品推荐
相关产品推荐

