2012-03-12 5 views
2

웹 스크레이퍼를 구축 중입니다. 기본적으로, 어떤 소프트가 할 것입니다 것은 :Python/PySide/PyQt의 멀티 스레드 웹 스크래핑

  1. 사용자가 (나) 일부 데이터 (IDS) 입력 - 아이디가 복잡하고, 그래서 그냥 숫자 그 ID를 기반으로
  2. 는 스크립트가 http://localhost/ID
방문을

이 작업을 수행하는 가장 좋은 방법은 무엇입니까? 그래서 나는 그것을 위해 20-30 개의 동시 연결을 찾고 있습니다.

간단한 루프가 해결책일까요? 이 루프는 QThreads (Qt 앱)를 시작하므로 동시에 실행됩니다.

그러나 루프와 함께보고있는 문제는 전에 사용되지 않은 ID (예 : iteration/thread가 사용되기 직전에 사용 된 ID)를 사용하도록 지시하는 방법입니다. 사용 된 ID를 추적하고 사용되지 않는 ID를 QThreads에 위임하는 일종의 "위임자"함수가 필요합니까?

은 지금은 몇 가지 코드를 작성했습니다하지만이 정확한지 잘 모르겠습니다 :

class GUI(QObject): 

    def __init__(self): 
     print "GUI CLASS INITIALIZED!!!" 
     self.worker = Worker() 

     for i in xrange(300): 
      QThreadPool().globalInstance().start(self.worker) 

class Worker(QRunnable): 

    def run(self): 
     print "Hello world from thread", QThread.currentThread() 

지금 나는이 정말 내가 원하는 것을 얻을 수 있는지 확실하지 않습니다. 실제로 별도의 스레드에서 실행되고 있습니까? 나는 이것이 실행될 때마다 currentThread()이 동일하기 때문에 묻고 있는데, 그렇게 보이지 않습니다.

기본적으로 내 질문은 여러 개의 동일한 QThread를 동시에 어떻게 실행합니까?

미리 답변 해 주셔서 감사합니다.

+0

GUI와 논리를 구분하고 GUI에만 QT를 사용해야합니다. 크롤러 로직은 순수한 파이썬으로 작성되거나 [scrapy] (http://scrapy.org/) – Dikei

답변

5

Dikei가 말했듯이 Qt는 여기에서 빨간색 청어입니다. 파이썬 스레드를 사용하는 것에 집중하면 코드를 훨씬 간단하게 유지할 수 있습니다.

아래 코드에는 job_queue이 있으며 실행될 작업이 포함되어 있습니다. 우리는 또한 전달 된 큐에서 작업을 가져와 실행하는 worker_thread 함수를 가지고 있습니다. 여기에 그것은 단지 임의의 시간 동안 잠든다. 여기서 중요한 점은 set.pop이 스레드로부터 안전하다는 것입니다.

우리는 스레드 오브젝트 배열 workers을 생성하고 각각을 생성 할 때 start을 호출합니다. Python documentation에서 threading.Thread.start는 별도의 제어 스레드에서 주어진 호출 가능 함수를 실행합니다. 마지막으로 각 작업자 스레드를 종료하고 종료 할 때까지 차단합니다.

import threading 
import random 
import time 

pool_size = 5 

job_queue = set(range(100)) 

def worker_thread(queue): 
    while True: 
     try: 
      job = queue.pop() 
     except KeyError: 
      break 

     print "Processing %i..." % (job,) 
     time.sleep(random.random()) 

    print "Thread exiting." 

workers = [] 
for thread in range(pool_size): 
    workers.append(threading.Thread(target=worker_thread, args=(job_queue,))) 
    workers[-1].start() 

for worker in workers: 
    worker.join() 

print "All threads exited" 
+1

과 같은 기존 크롤러를 재사용해야합니다. 실제로는 다릅니다. 스레드가 GUI와 통신 할 필요가 있다면,'QThread'가 더 좋고 더 간단 할 것입니다. – Avaris

+0

@Avaris와 마찬가지로 스레드는 GUI 스레드와 통신해야하며 기존 코드는 주로 QThread로 작성되므로 파이썬의 내장 스레딩 모듈 대신 사용해야합니다. 자세한 응답을 원하신다면 어차피 +1 했습니까? –

+0

time.sleep (random.random())을 사용하면 어떤 이점이 있습니까? –