首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python -多个Tor代理上的并发HTTP请求

问python -多个Tor代理上的并发HTTP请求
EN

Stack Overflow用户
提问于 2018-03-28 06:33:41
回答 1查看 2.6K关注 0票数 2

我的计算机上运行着多个Tor客户端,每个客户端都可以通过自己的端口访问(当前端口为9050-9054)。我希望通过这些Tor客户端同时请求大量URL,并设置速率限制,以便在任何给定的Tor端口上每N秒钟只发出一个请求,并且每个端口都使用一个唯一的退出节点(也就是说,从来没有两个tor端口同时从同一个IP发出请求)。

其目标是能够从受IP限制的网站/API中刮取,使请求看起来来自多个不同的IP,每个IP以最大的速度消费。匿名并不是真正的目标-- Tor的使用仅仅是为了创建大量的is来欺骗速率限制者认为这是一群不同的用户请求数据。因此,例如,如果API限制在每秒一个请求,并且我有10个正在以这个速率请求的tor客户机运行,那么我可以以最高速率的10倍提出请求.

下面是我到目前为止拥有的代码,它同时通过我的Tor客户机池获取所有URL:

代码语言:javascript
复制
import requests
from concurrent.futures import ThreadPoolExecutor, as_completed
from time import sleep
from datetime import datetime 
from threading import Lock
import logging

logging.basicConfig(filename='log.txt', level=logging.DEBUG)

tor_ports = ['9050', '9051', '9052', '9053', '9054']
port_locks = {port: Lock() for port in tor_ports}

delay = 1   # wait N seconds between requests on same port

ua_string = 'Mozilla/5.0 (X11; Linux x86_64; rv:59.0) Gecko/20100101 Firefox/59.0'

# Create a new HTTP Requests Session routed through one of our Tor proxies
def newTorSession(port):
    assert port in tor_ports
    session = requests.session()
    session.proxies = {'http':  'socks5://127.0.0.1:' + port,
                       'https': 'socks5://127.0.0.1:' + port}
    return session

# Go through the list of all Tor proxies and return one that isn't locked
def getFreeTorPort(hangtime):
    start = datetime.now()
    while (datetime.now() - start).total_seconds() < hangtime: 
        for port in tor_ports:
            if port_locks[port].locked():
                next; # port in use ... try the next one
            else:
                port_locks[port].acquire()
                return port

    return None # this is when we exceed hangtime ... should be an exception we catch


# URL to fetch, and how long to sleep() after request
def torGet(url, delay):

    port = getFreeTorPort(60)
    session = newTorSession(port)

    try:
        response = session.get(url, headers = {'User-Agent': ua_string})
    except requests.exception.RequestException as e:
        logging.warning("Request of URL " + url + " failed with exception: " + e)

    sleep(delay) # Pause for `delay` seconds after request

    port_locks[port].release()

    return response


# given a list of URLs, use multiple threads with own tor client to GET items
def torGetConcurrent(urls):
    responses = []

    with ThreadPoolExecutor(max_workers=len(tor_ports)) as executor:
        futures = [executor.submit(torGet, url, delay) for url in urls]
        responses = [f.result() for f in as_completed(futures)]

    return responses

我的问题是,如何确保每个Tor客户端总是使用不同的退出IP?也就是说,我想确保如果我运行10个tor客户端,我将始终使用10个唯一的退出节点。按照我目前设置的方式,有时会有多个客户端使用相同的出口,这导致我超过了每个IP的速率限制。我知道,我可以在ExitNodes字段中为每个客户端显式指定torrc字段中的退出节点列表,但我想知道是否有一种方法可以通过python脚本检查这一点,因为我不想手动使用退出节点列表来更新配置文件,而且只要它们都是唯一的,我也不关心它们使用的是哪些退出节点。

谢谢!

EN

回答 1

Stack Overflow用户

发布于 2018-03-28 20:41:46

我不一定会说Tor有“大量的I”。目前约有850个出口可用,其中一些出口可能超载,无法使用。

无论如何,尝试为所有出口(几个网站发布这些列表)或您想要使用的国家的出口建立指纹列表,并将每个tor客户端的ExitNodes配置设置为特定的指纹,以便它们没有一个同时使用相同的指纹。这将比向各个客户端发送NEWNYM信号更成功,希望它们没有一个同时重叠,并且必须运行缓慢的检查来查看任何给定客户端正在使用的出口。

编辑:

要执行我描述的操作,获取一个出口列表(即https://check.torproject.org/exit-addresses或https://torstatus.blutmagie.de/)并将它们拉到您选择的列表中,这样您就可以随意选择唯一的指纹列表,然后使用词干连接到每个实例的控制端口。连接后,将每个实例的配置值ExitNodes设置为指纹之一。ExitNodes可以是国家、节点列表,也可以是单个节点。当设置为单个节点时,您基本上是将该中继用作出口的客户端。这确保两个客户端不会同时使用相同的出口继电器。一旦你准备好循环它们,设置ExitNodes到一个新的指纹,并调用SIGNAL NEWNYN来构建新的电路。

这样做可能比检查每个实例并强制一个新的IP (如果其中任何一个是相同的话)更快。这样就不可能有一个实例在会话之间构建一个新的电路,并且在不知道的情况下使用重复的IP。

目前,如果不检查外部站点上的IP,就无法使用Python或任何其他语言获取退出IP或指纹。通常可以关闭的是使用控制端口查看活动电路的列表,从中提取退出指纹,并从目录状态请求中找到它的IP。由于Tor可以同时具有多个电路,所以您无法判断您的脚本可能使用哪一个。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49527625

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档