使用tor代理时的多线程爬虫

Posted

技术标签:

【中文标题】使用tor代理时的多线程爬虫【英文标题】:multithreaded crawler while using tor proxy 【发布时间】:2018-01-14 00:50:19 【问题描述】:

我正在尝试构建使用 tor 代理的多线程爬虫: 我正在使用以下方式建立 Tor 连接:

from stem import Signal
from stem.control import Controller
controller = Controller.from_port(port=9151)
def connectTor():
    socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9150)
    socket.socket = socks.socksocket


def renew_tor():
    global request_headers
    request_headers = 
        "Accept-Language": "en-US,en;q=0.5",
        "User-Agent": random.choice(BROWSERS),
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
        "Referer": "http://thewebsite2.com",
        "Connection": "close"
    

    controller.authenticate()
    controller.signal(Signal.NEWNYM)

这里是网址提取器:

def get_soup(url):
    while True:
        try:
            connectTor()
            r = requests.Session()
            response = r.get(url, headers=request_headers)
            the_page = response.content.decode('utf-8',errors='ignore')
            the_soup = BeautifulSoup(the_page, 'html.parser')
            if "captcha" in the_page.lower():
                print("flag condition matched while url: ", url)
                #print(the_page)
                renew_tor()
            else:
                return the_soup
                break
        except Exception as e:
            print ("Error while URL :", url, str(e))

然后我正在创建多线程获取作业:

with futures.ThreadPoolExecutor(200) as executor:
            for url in zurls:
                future = executor.submit(fetchjob,url)

然后我收到以下错误,当我使用多处理时我没有看到:

 Socket connection failed (Socket error: 0x01: General SOCKS server failure)

如果有任何建议避免袜子错误并提高爬取方法的性能以使其成为多线程,我将不胜感激。

【问题讨论】:

这能解决吗? ***.com/questions/28035413/… 虽然我的代码受到链接中代码的启发,但我正在尝试构建多线程代码,所以我遇到了问题。 【参考方案1】:

这是为什么猴子修补 socket.socket 不好的一个完美例子。

这会将 all socket 连接(几乎所有东西)使用的套接字替换为 SOCKS 套接字。

稍后你去连接控制器时,它会尝试使用 SOCKS 协议进行通信,而不是建立直接连接。

由于您已经在使用 requests,我建议您摆脱 SocksiPy 和 socks.socket = socks.socksocket 代码,并使用请求中内置的 SOCKS proxy 功能:

proxies = 
    'http': 'socks5h://127.0.0.1:9050',
    'https': 'socks5h://127.0.0.1:9050'


response = r.get(url, headers=request_headers, proxies=proxies)

【讨论】:

非常感谢,这解决了套接字问题,但是我得到了(由 SSLError(SSLError("bad handshake: SysCallError(-1, 'Unexpected EOF')",),) ) 该错误与获取 URL 的请求有关吗?如果您只是尝试通过 SOCKS 代理向目标站点发出一个请求,会发生这种情况吗? 此错误并非一直发生。许多线程都成功了。即使我在单线程模式下运行,有时也会出现此错误。但是,由于我已经使 get_soup() 方法具有弹性,我仍然能够爬行。

以上是关于使用tor代理时的多线程爬虫的主要内容,如果未能解决你的问题,请参考以下文章

C#爬虫爬虫的多线程如何实现

python多线程和多线程问题

基于Thread+queue的多线程爬虫

一个简单的多线程Python爬虫

关闭 MFC 对话框时的多线程对象破坏

Python多线程爬虫