Python中如何使用socks.wrapmodule实现代理功能?
def btest():
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, '58.243.107.xx', 4365)
socks.wrapmodule(smtplib)
burl = 'http://www.ip138.com/ips1388.asp'
resp1 = requests.get(burl).text
print(resp1)
代码如上,resp1 的结果 ip 是'58.243.107.xx'
为何在使用 socks.wrapmodule(smtplib)后会影响 requests 的使用
或者说,有办法避免或解决这个 bug 的好方案吗?
菜鸟一枚,各位轻虐
Python中如何使用socks.wrapmodule实现代理功能?
4 回复
socks 是什么库?
你自己审计过源码吗?
import socks
import socket
import urllib.request
# 1. 设置代理类型和地址
socks.set_default_proxy(
socks.SOCKS5, # 代理类型:SOCKS4/SOCKS5/HTTP
addr="127.0.0.1", # 代理服务器地址
port=1080 # 代理端口
)
# 2. 关键步骤:包装socket模块
socket.socket = socks.socksocket
# 3. 验证代理是否生效
try:
# 方法1:直接测试socket连接
test_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
test_socket.settimeout(5)
test_socket.connect(("www.google.com", 80))
print("Socket代理测试成功")
test_socket.close()
# 方法2:使用urllib测试(会自动使用包装后的socket)
response = urllib.request.urlopen("http://httpbin.org/ip", timeout=10)
print("当前代理IP:", response.read().decode())
except Exception as e:
print(f"代理连接失败: {e}")
# 4. 实际使用示例
def fetch_with_proxy(url):
"""通过代理获取网页内容"""
req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
return urllib.request.urlopen(req).read()
# 使用示例
if __name__ == "__main__":
# 注意:设置一次后,整个程序的所有socket连接都会走代理
html = fetch_with_proxy("https://api.ipify.org?format=json")
print("通过代理获取的外网IP:", html.decode())
核心原理:
socks.wrapmodule 实际上是通过猴子补丁(monkey-patching)替换了 socket.socket 类,让所有网络请求自动通过SOCKS代理。上面的代码展示了标准做法:先设置代理参数,然后执行 socket.socket = socks.socksocket。
重要提醒:
- 这种方法会影响整个进程的所有socket连接
- 如果需要多代理切换,需要动态重新设置
- 某些库(如requests)可能有自己的代理配置方式
一句话总结: 用 socket.socket = socks.socksocket 全局替换就能让所有网络请求走代理。
使用一个库就要阅读审计一个库的源码?


