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 全局替换就能让所有网络请求走代理。

使用一个库就要阅读审计一个库的源码?

难道你们都不看源码的 23333

回到顶部