2012-02-18 4 views
2

나는 Beautiful Soup을 사용하여 웹 사이트를 데이터 마이닝하고있다. 첫 번째 페이지는 Scoutmob's map으로, 각 도시를 잡고 페이지를 열고 해당 도시의 각 거래 URL을 가져옵니다.파이썬 작성자 작업 큐

현재 스레드를 사용하지 않고 모든 것이 순차적으로 처리되고 있습니다. 약 500 개의 거래 (모든 도시에서)에 대해 내 프로그램은 현재 약 400 초가 걸립니다.

실습을 위해 스레딩을 사용하도록 코드를 수정하고 싶습니다. 파이썬에서 큐를 생성하는 방법에 대해 tutorials and examples을 읽었지만 500 개의 스레드를 작성하여 500 개의 URL을 처리하고 싶지 않습니다.

대신 모든 URL을 처리하기 위해 약 20 개의 (작업자) 스레드를 생성하려고합니다. 누가 20 개의 스레드가 대기열에서 500 개의 URL을 처리 할 수 ​​있는지 예제를 보여줄 수 있습니까?

각 작업자가 큐에서 처리되지 않은 URL을 가져오고 데이터 마인이 처리되지 않은 다른 URL에서 작업하도록합니다. 각 작업자는 큐에 더 이상 URL이 없을 때만 종료됩니다.

한편, 각 작업자는 데이터 마이닝이지만 데이터베이스에 내용을 씁니다. 따라서 데이터베이스에 스레딩 문제가있을 수 있지만 다른 날의 또 다른 질문입니다 .-).

미리 감사드립니다.

+0

"나는 각 근로자가 처리되지 않은 큐에서 URL 및 데이터 광산, 다음 번 완료를 잡고 싶다"답변입니다 :

#!/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 

이 출력을 얻을 수 있습니다. 너는 무엇을 더 알고 싶니? 대기열의 get 메소드를 사용하는 방법을 묻고 있습니까? –

+0

대기열에 더 이상 항목이 없을 때까지 스레드가 "열린"상태를 유지하는 방법이 아닌 것 같아요. 먼저 대기열을 완전히 채워야하나요, 그래서 내가 대기열에 "실시간"회의를 만들 수 있습니까? 그리고 스레드가 멈추라 말할 때까지 계속 작동합니까? – hobbes3

+0

질문을 이해할 수 없습니다. 대기열이 비어있을 때 스레드가 마술처럼 멈추는 것으로 가정하고 있습니까? 왜 그들은 그렇게 할 것인가? –

답변

2

예를 들어 작업자 대기열을 만드는 경우에는 과도한 행동 일 수 있습니다. 더 느린 HTML을 구문 분석하는 대신 각 페이지에 대해 게시 된 RSS 피드를 가져 오는 것이 더 나을 수도 있습니다. 나는 아래의 빠른 스크립트를 합쳐서 ~ 13 초를 파싱했다. 도시를 움켜 쥘 때 ~ 8 초, 구문 분석 할 때 ~ 5 초 모두 rss 피드.

오늘은 13 개 도시에서 총 310 개의 거래가 있습니다 (나열된 총 20 개 도시가 있지만 그 중 7 개가 "예정"으로 표시됨).

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이 없을 때만 종료됩니다.