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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 21:27:41