python3给socket模块设置代理

最近需要在公司学习socket编程,但是不能直接连接外网,需要设置一个代理才能正常访问。报错示例:

import socket

def blocking(wd):
    sock = socket.socket()
    sock.connect(('www.baidu.com',80)) # 连接百度
    request = 'GET {} HTTP/1.0\r\nHost:www.baidu.com\r\n\r\n'.format('/s?wd={}'.format(wd)) # 构造http请求头
    response = b''  # 用于接收数据
    sock.send(request.encode())  # 发送http请求
    chunk = sock.recv(1024)  # 一次接收1024字节数据
    while chunk:  # 循环接收数据,若没有数据了说明已接收完
        response += chunk  # 字符串拼接
        chunk = sock.recv(1024)
    print(response.decode())

if __name__ == '__main__':
    blocking('python')

解决办法:要使用代理,需要用到socks这两个包。socks在python3中不是自带的,所以需要通过pip install PySocks这个模块。 
增加如下带代码即可:

import socks
import socket
socks.set_default_proxy(socks.HTTP, '地址', 端口, True, 用户名, 密码)
socket.socket = socks.socksocket

修改后示例:

import socket
import socks  # pip install PySocks
socks.set_default_proxy(socks.HTTP,addr='192.168.105.71',port=80) #设置socks代理
socket.socket = socks.socksocket  # 把代理应用到socket
def blocking(wd):
    sock = socket.socket()
    sock.connect(('www.baidu.com',80)) # 连接百度
    request = 'GET {} HTTP/1.0\r\nHost:www.baidu.com\r\n\r\n'.format('/s?wd={}'.format(wd)) # 构造http请求头
    response = b''  # 用于接收数据
    sock.send(request.encode())  # 发送http请求
    chunk = sock.recv(1024)  # 一次接收1024字节数据
    while chunk:  # 循环接收数据,若没有数据了说明已接收完
        response += chunk  # 字符串拼接
        chunk = sock.recv(1024)
    print(response.decode())

if __name__ == '__main__':
    blocking('python')

可以看到已经正常请求到百度。

注意:socks的类型,即set_default_proxy的第一个参数,网上很多资料写的都是socks.SOCKS5。如果出现下面这个错误,请检查代理服务的类型,我这里改成socks.HTTP即可正常发送请求:

socks.GeneralProxyError: Socket error: Connection closed unexpectedly

 

posted @ 2018-07-24 16:01  purplelavender  阅读(16196)  评论(0编辑  收藏  举报