【问题标题】:Can I change SOCKS proxy within a function using SocksiPy?我可以使用 SocksiPy 在函数中更改 SOCKS 代理吗?
【发布时间】:2015-12-17 09:07:56
【问题描述】:

我正在尝试编写一个函数,该函数将获取一个 URL 并返回该 URL 的内容。还有一个附加参数 (useTor),当设置为 True 时,将使用 SocksiPy 通过 SOCKS 5 代理服务器(在本例中为 Tor)路由请求。

我可以为所有连接全局设置代理,但我无法解决两件事:

  1. 如何将此设置移动到一个函数中,以便可以在 useTor 变量上决定它?我无法在函数中访问socks,也不知道该怎么做。

  2. 我假设如果我不设置代理,那么下次发出请求时它会直接发送。 SocksiPy 文档似乎没有提供任何关于如何重置代理的指示。

谁能给点建议?我的(初学者)代码如下:

import gzip
import socks
import socket

def create_connection(address, timeout=None, source_address=None):
    sock = socks.socksocket()
    sock.connect(address)
    return sock

# next line works just fine if I want to set the proxy globally
# socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9050)
socket.socket = socks.socksocket
socket.create_connection = create_connection

import urllib2
import sys

def getURL(url, useTor=False):

    if useTor:
        print "Using tor..."
        # Throws- AttributeError: 'module' object has no attribute 'setproxy'
        socks.setproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9050)
    else:
        print "Not using tor..."
        # Not sure how to cancel the proxy, assuming it persists

    opener = urllib2.build_opener()
    usock = opener.open(url)
    url = usock.geturl()

    encoding = usock.info().get("Content-Encoding")

    if encoding in ('gzip', 'x-gzip', 'deflate'):
        content = usock.read()
        if encoding == 'deflate':
            data = StringIO.StringIO(zlib.decompress(content))
        else:
            data = gzip.GzipFile('', 'rb', 9, StringIO.StringIO(content))
        result = data.read()
    else:
        result = usock.read()

    usock.close()

    return result

# Connect to the same site both with and without using Tor    

print getURL('https://check.torproject.org', False)
print getURL('https://check.torproject.org', True)

【问题讨论】:

    标签: python proxy socks


    【解决方案1】:

    示例

    只需不带参数调用socksocket.set_proxy,这将有效地删除任何以前设置的代理设置。

    import socks
    sck = socks.socksocket ()
    
    # use TOR
    sck.setproxy (socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9050)
    
    # reset to normal use
    sck.setproxy ()
    

    详情

    通过查看socks.py 的来源,并深入研究socksocket.setproxy 的内容,我们很快意识到,为了丢弃任何以前的代理属性,我们只需调用没有附加参数的函数(除了 self)。

    class socksocket(socket.socket):
        ... # additional functionality ignored
    
        def setproxy(self,proxytype=None,addr=None,port=None,rdns=True,username=None,password=None):
            """setproxy(proxytype, addr[, port[, rdns[, username[, password]]]])
            Sets the proxy to be used.
            proxytype - The type of the proxy to be used. Three types
                    are supported: PROXY_TYPE_SOCKS4 (including socks4a),
                    PROXY_TYPE_SOCKS5 and PROXY_TYPE_HTTP
            addr -      The address of the server (IP or DNS).
            port -      The port of the server. Defaults to 1080 for SOCKS
                    servers and 8080 for HTTP proxy servers.
            rdns -      Should DNS queries be preformed on the remote side
                    (rather than the local side). The default is True.
                    Note: This has no effect with SOCKS4 servers.
            username -  Username to authenticate with to the server.
                    The default is no authentication.
            password -  Password to authenticate with to the server.
                    Only relevant when username is also provided.
            """
            self.__proxy = (proxytype,addr,port,rdns,username,password)
    
        ... # additional functionality ignored
    

    注意:当即将协商新连接时,实现将使用 self.__proxy 的内容,除非可能需要的元素是 None(在这种情况下,设置被简单地忽略)。

    【讨论】:

    • 谢谢。不幸的是,将sck = socks.socksocket() 放在函数之外,然后在getURL 内部调用sck.setproxy(socks.PROXY_TYPE_SOCKS5, "192.168.0.1", 9050) 不会引发错误,但也不会通过tor 路由任何东西。你也可以帮忙吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-21
    • 2016-12-04
    • 1970-01-01
    相关资源
    最近更新 更多