0

我正在使用 urllib2 进行数据抓取调用,但它们每个都需要大约 1 秒才能完成。我试图测试是否可以将 URL 调用循环多线程化到具有不同偏移量的线程中。

我现在使用 update_items() 方法执行此操作,其中第一个和第二个参数是执行循环的偏移量和限制:

import threading
t1 = threading.Thread(target=trade.update_items(1, 100))
t2 = threading.Thread(target=trade.update_items(101, 200))
t3 = threading.Thread(target=trade.update_items(201, 300))

t1.start()
t2.start()
t3.start()

#t1.join()
#t2.join()
#t3.join()

像代码一样,我试图注释掉 join() 以防止线程等待,但似乎我对这个库的理解是错误的。我将 print() 函数插入到 update_items() 方法中,有趣的是它表明它仍然只是在串行例程中循环,而不是所有 3 个线程并行,就像我想要实现的那样。

我的正常抓取协议大约需要 5 个小时才能完成,而且它只是非常小的数据,但 HTTP 调用总是需要一些时间。我想多线程这个任务至少几次,以将提取时间至少缩短到 30-45 分钟左右。

4

2 回答 2

3

要并行获取多个 url,一次限制为 20 个连接:

import urllib2
from multiprocessing.dummy import Pool

def generate_urls(): # generate some dummy urls
    for i in range(100):
        yield 'http://example.com?param=%d' % i

def get_url(url):
    try: return url, urllib2.urlopen(url).read(), None
    except EnvironmentError as e:
         return url, None, e

pool = Pool(20) # limit number of concurrent connections
for url, result, error in pool.imap_unordered(get_url, generate_urls()):
    if error is None:
       print result,
于 2013-01-29T23:45:43.727 回答
2

Paul Seeb 已正确诊断出您的问题。

您正在调用trade.update_items,然后将结果传递给threading.Thread构造函数。因此,您会得到串行行为:您的线程不做任何工作,并且每个线程的创建都会延迟到update_items调用返回。

正确的形式是threading.Thread(target=trade.update_items, args=(1, 100)第一行,后面的也一样。这会将update_items函数作为线程入口点传递,并将其*[1, 100]作为其位置参数。

于 2013-01-29T21:50:28.290 回答