Python基于urllib实现运行时切换代理的问题与优化咨询
解决Python运行时切换代理的问题
首先,你的代码没法正常运行大概率有两个核心原因:
- 你请求的
icanhazip.com是HTTPS站点,但你的代理字典只配置了http协议,HTTPS请求不会走这个代理,导致请求直接用本地网络或者失败; read()返回的是字节流,没有解码成可读的字符串,打印出来会是乱码或者字节格式的内容。
先给你修正后的urllib版本代码,保证能正常运行:
import urllib.request # 注意同时配置http和https协议的代理 proxydict = {'http': 'http://45.63.66.17:8080', 'https': 'http://45.63.66.17:8080'} proxydict2 = {'http': 'http://3.212.39.212:80', 'https': 'http://3.212.39.212:80'} def create_opener(proxy_dict): proxy_support = urllib.request.ProxyHandler(proxy_dict) # 加上默认处理器,避免无法处理重定向、Cookie等场景 opener = urllib.request.build_opener(proxy_support, urllib.request.HTTPHandler) return opener opener1 = create_opener(proxydict) opener2 = create_opener(proxydict2) try: # 解码字节流为字符串,同时设置超时避免请求卡住 print(opener1.open('https://icanhazip.com', timeout=10).read().decode('utf-8').strip()) print(opener2.open('https://icanhazip.com', timeout=10).read().decode('utf-8').strip()) except Exception as e: print(f"请求出错: {e}")
更优雅的实现方式:用requests库
urllib本身比较繁琐,用requests库可以大幅简化代码,可读性和复用性都更强:
首先安装requests(如果没装的话):
pip install requests
然后实现代码:
import requests def get_ip_with_proxy(proxy_url): # 构造requests需要的代理格式,同时覆盖http和https请求 proxies = { 'http': proxy_url, 'https': proxy_url } try: response = requests.get('https://icanhazip.com', proxies=proxies, timeout=10) response.raise_for_status() # 主动抛出HTTP状态码错误 return response.text.strip() except requests.exceptions.RequestException as e: return f"请求失败: {e}" # 切换代理只需要传入不同的代理字符串,非常直观 print(get_ip_with_proxy('http://45.63.66.17:8080')) print(get_ip_with_proxy('http://3.212.39.212:80'))
这种方式的优势:
- 代码更简洁,不需要手动构建opener等底层组件;
- 异常处理更友好,requests封装了所有常见的网络异常类型;
- 切换代理的成本极低,直接传入不同的代理字符串即可;
- 自动处理字节流解码,直接返回可读的字符串结果。
另外,如果你的代理需要用户名密码验证,只需要把代理字符串改成http://username:password@ip:port格式即可,urllib和requests都支持这种格式。
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

