2012-02-18 5 views
2

Я использую интеллектуальный анализ данных с использованием Beautiful Soup. Первая страница - Scoutmob's map, где я захватываю каждый город, открываю страницу и захватываю URL-адрес каждой сделки в этом городе.Python, создающий рабочие очереди

В настоящее время я не использую нити, и все обрабатывается последовательно. Для всех 500 сделок (из всех городов) моя программа в настоящее время занимает около 400 секунд.

Для практики я хотел изменить свой код, чтобы использовать потоки. Я прочитал некоторые tutorials and examples о том, как создавать очереди в Python, но я не хочу создавать 500 потоков для обработки 500 URL-адресов.

Вместо этого я хочу создать около 20 (рабочих) потоков для обработки всех URL-адресов. Может ли кто-нибудь показать мне пример того, как 20 потоков могут обрабатывать 500 URL-адресов в очереди?

Я хочу, чтобы каждый работник получал необработанный URL-адрес из очереди, а мои данные, после их завершения, работали над другим необработанным URL-адресом. Каждый рабочий только выходит, когда в очереди больше URL-адресов.

Кстати, в то время как каждый рабочий - это интеллектуальный анализ данных, он также записывает содержимое в базу данных. Таким образом, в базе данных могут возникать проблемы с потоками, но это еще один вопрос в другой день :-).

Заранее благодарен!

+0

«Я хочу, чтобы каждый работник, чтобы захватить необработанный URL из очереди, и шахта данных, затем один раз закончил,» ответ. Что еще вы хотите знать? Вы спрашиваете, как использовать метод get очереди? –

+0

Я думаю, я не был тем, как потоки будут оставаться «открытыми», пока в очереди не останется больше предметов. Нужно ли сначала полностью заполнять очередь, так что я могу создать как «живое» соединение в очереди, и потоки продолжают работать, пока я не остановлюсь? – hobbes3

+0

Я не могу понять ваш вопрос. Вы предполагаете, что потоки магически прекращаются, когда очередь пуста? Почему они это сделали? –

ответ

2

Для вашего примера создание рабочих очередей, вероятно, является излишним. Возможно, вам повезет, если вы возьмете rss-канал, опубликованный для каждой из страниц, вместо того, чтобы пытаться анализировать HTML-код, который медленнее. Я ударил по маленькому скрипту ниже, который анализирует его в течение ~ 13 секунд ... ~ 8 секунд, чтобы захватить города и ~ 5 секунд, чтобы разобрать все rss-каналы.

В сегодняшнем беге он захватывает 310 сделок из 13 городов (в общей сложности 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 
+0

Спасибо за ответ, но что-то не так ... Есть 556 сделок со всех городов. Чтение только RSS-канала для меня недостаточно, так как RSS-канал не сообщает мне достаточно информации по сделке (например, бизнес-адрес и номер телефона). Также кажется, что в RSS-каналах также есть новости, которые мне все равно. Поэтому мне все равно нужно открыть каждую страницу отдельных клиентов.И ваш код в значительной степени берет RSS-канал и использует Xpath для захвата всей информации? – hobbes3

0

Просто реализуйте его. Вы довольно много говорили сами через ответ прямо

Я хочу, чтобы каждый работник, чтобы захватить необработанный URL из очереди, и шахт данных, затем один раз закончила работу, на другой необработанном URL. Каждый рабочий только выходит, когда в очереди больше URL-адресов.

Смежные вопросы