1. 程式人生 > >爬蟲之多線程

爬蟲之多線程

3.1 保存到文件 執行 timeout 如何使用 queue som true 方法

1. 引入

我們平常寫的爬蟲都是單個線程的?這怎麽夠?一旦一個地方卡到不動了,那不就永遠等待下去了?為此我們可以使用多線程或者多進程來處理。

2. 如何使用

爬蟲使用多線程來處理網絡請求,使用線程來處理URL隊列中的url,然後將url返回的結果保存在另一個隊列中,其它線程在讀取這個隊列中的數據,然後寫到文件中去

3. 主要組成部分

3.1 URL隊列和結果隊列

將將要爬去的url放在一個隊列中,這裏使用標準庫Queue。訪問url後的結果保存在結果隊列中

初始化一個URL隊列

from queue import Queue
urls_queue = Queue()
out_queue = Queue()

3.2 請求線程

使用多個線程,不停的取URL隊列中的url,並進行處理:

import threading

class ThreadCrawl(threading.Thread):
    def __init__(self, queue, out_queue):
        threading.Thread.__init__(self)
        self.queue = queue
        self.out_queue = out_queue

    def run(self):
        while True:
            item = self.queue.get()

如果隊列為空,線程就會被阻塞,直到隊列不為空。處理隊列中的一條數據後,就需要通知隊列已經處理完該條數據

3.3 處理線程

處理結果隊列中的數據,並保存到文件中。如果使用多個線程的話,必須要給文件加上鎖

lock = threading.Lock()
f = codecs.open(‘out.txt‘, ‘w‘, ‘utf8‘)

當線程需要寫入文件的時候,可以這樣處理:

with lock:
    f.write(something)

4. Queue模塊中的常用方法:

Python的Queue模塊中提供了同步的、線程安全的隊列類,包括FIFO(先入先出)隊列Queue,LIFO(後入先出)隊列LifoQueue,和優先級隊列PriorityQueue。這些隊列都實現了鎖原語,能夠在多線程中直接使用。可以使用隊列來實現線程間的同步

  • Queue.qsize() 返回隊列的大小
  • Queue.empty() 如果隊列為空,返回True,反之False
  • Queue.full() 如果隊列滿了,返回True,反之False
  • Queue.full 與 maxsize 大小對應
  • Queue.get([block[, timeout]])獲取隊列,timeout等待時間
  • Queue.get_nowait() 相當Queue.get(False)
  • Queue.put(item) 寫入隊列,timeout等待時間
  • Queue.put_nowait(item) 相當Queue.put(item, False)
  • Queue.task_done() 在完成一項工作之後,Queue.task_done()函數向任務已經完成的隊列發送一個信號
  • Queue.join() 實際上意味著等到隊列為空,再執行別的操作

爬蟲之多線程