Python创建工作队列

时间:2012-02-18 23:22:14

标签: python multithreading beautifulsoup

我使用Beautiful Soup对网站进行数据挖掘。第一页是Scoutmob's map,我抓住每个城市,打开页面,抓住该城市每笔交易的网址。

目前我没有使用线程,所有内容都是按顺序处理的。对于所有500个交易(来自所有城市),我的程序目前大约需要400秒。

对于练习,我想修改我的代码以使用线程。我已经阅读了一些关于如何在Python中创建队列的tutorials and examples,但我不想创建500个线程来处理500个URL。

相反,我想创建大约20个(工作者)线程来处理所有URL。 有人能告诉我一个例子,20个线程如何处理队列中的500个URL?

我希望每个工作人员从队列中获取未处理的URL,并且数据挖掘,然后完成后,处理另一个未处理的URL。每个工作程序仅在队列中没有其他URL时退出。

顺便说一句,虽然每个worker都是数据挖掘,但它也会将内容写入数据库。因此,数据库中的线程可能存在问题,但这是另一天的另一个问题:-)。

提前致谢!

2 个答案:

答案 0 :(得分:2)

对于您的示例,创建工作队列可能有点过分。如果你抓住为每个页面发布的rss feed而不是试图解析速度较慢的HTML,你可能会有更好的运气。我把下面快速的小脚本拼凑在一起,总共花了大约13秒钟~~ 8秒钟来抓住城市,大约5秒钟解析所有 rss feed。

在今天的比赛中,它从13个城市获得了310笔交易(总共列出了20个城市,但其中7个被列为“即将推出”)。

#!/usr/bin/env python

from lxml import etree, html
from urlparse import urljoin
import time

t = time.time()
base = 'http://scoutmob.com/'
main = html.parse(base)
cities = [x.split('?')[0] for x in main.xpath("//a[starts-with(@class, 'cities-')]/@href")]
urls = [urljoin(base, x + '/today') for x in cities]
docs = [html.parse(url) for url in urls]
feeds = [doc.xpath("//link[@rel='alternate']/@href")[0] for doc in docs]
# filter out the "coming soon" feeds
feeds = [x for x in feeds if x != 'http://feeds.feedburner.com/scoutmob']
print time.time() - t
print len(cities), cities
print len(feeds), feeds

t = time.time()
items = [etree.parse(x).xpath("//item") for x in feeds]
print time.time() - t
count = sum(map(len, items))
print count

产生此输出:

7.79690480232
20 ['/atlanta', '/new-york', '/san-francisco', '/washington-dc', '/charlotte', '/miami', '/philadelphia', '/houston', '/minneapolis', '/phoenix', '/san-diego', '/nashville', '/austin', '/boston', '/chicago', '/dallas', '/denver', '/los-angeles', '/seattle', '/portland']
13 ['http://feeds.feedburner.com/scoutmob/atl', 'http://feeds.feedburner.com/scoutmob/nyc', 'http://feeds.feedburner.com/scoutmob/sf', 'http://scoutmob.com/washington-dc.rss', 'http://scoutmob.com/nashville.rss', 'http://scoutmob.com/austin.rss', 'http://scoutmob.com/boston.rss', 'http://scoutmob.com/chicago.rss', 'http://scoutmob.com/dallas.rss', 'http://scoutmob.com/denver.rss', 'http://scoutmob.com/los-angeles.rss', 'http://scoutmob.com/seattle.rss', 'http://scoutmob.com/portland.rss']
4.76977992058
310

答案 1 :(得分:0)

实施它。你几乎在那里通过答案谈了自己

  

我希望每个工作人员从队列中获取未处理的URL,并且数据挖掘,然后完成后,处理另一个未处理的URL。每个工作程序仅在队列中没有其他URL时退出。