使用代理的HTTP请求多线程处理

1 投票
1 回答
3467 浏览
提问于 2025-04-16 20:39

我看过一些类似的问题,但大家对如何处理HTTP的线程问题总是有很多不同的看法。

我具体想做的是:我在用Python 2.7,想尝试用线程来处理HTTP请求(特别是发送POST请求),并且每个请求都通过一个SOCKS5代理。现在我写的代码可以运行,但速度比较慢,因为它在每个请求(先到代理服务器,再到网页服务器)完成之前都不开始下一个请求。每个线程可能会发出不同的请求,并使用不同的SOCKS代理。

到目前为止,我只用过urllib2这个库。我也看过像PycURL这样的模块,但在Windows上用Python 2.7安装它非常困难,而我希望支持Windows并且就是在这个系统上编写代码。不过,我愿意尝试其他的模块。

我特别关注了这些问题:

Python urllib2.urlopen()很慢,需要更好的方法来读取多个网址

Python - 使用HTTPS的urllib2异步/线程请求示例

很多示例都被投了反对票,还引发了争论。假设评论者说的没错,使用像Twisted这样的异步框架来做客户端听起来会是最快的选择。不过,我在网上查了很多,发现它并不支持SOCKS5代理。我现在在用Socksipy模块,可能会尝试这样的代码:

socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, IP, port)
socks.wrapmodule(twisted.web.client)

不过我不知道这样是否可行,也不确定Twisted是否真的是我想用的。我也可以直接用线程模块,把它整合到我现在的urllib2代码里,但如果这样比Twisted慢很多,我可能就不想费这个劲了。有没有人能给点建议?

1 个回答

3

也许更简单的方法是直接使用gevent(或者eventlet)来帮助你打开很多与服务器的连接。这些库会对urllib进行一些修改,让它变得异步,同时你仍然可以写出看起来像同步的代码。相比于线程,它们的开销更小,这意味着你可以同时创建更多的连接(几千个连接也很正常)。

我用过类似的东西很多次(从这里抄来的):

urls = ['http://www.google.com', 'http://www.yandex.ru', 'http://www.python.org']

import gevent
from gevent import monkey

# patches stdlib (including socket and ssl modules) to cooperate with other greenlets
monkey.patch_all()

import urllib2


def print_head(url):
    print ('Starting %s' % url)
    data = urllib2.urlopen(url).read()
    print ('%s: %s bytes: %r' % (url, len(data), data[:50]))

jobs = [gevent.spawn(print_head, url) for url in urls]

撰写回答