Python爬蟲 初探多執行緒爬蟲

2021-07-06 05:02:25 字數 2860 閱讀 3889

上篇,我們已經建立了乙個基本的爬蟲,用來抓取動態網頁的資訊。經過測試,爬蟲的速度太慢,我們需要改進。這篇我會介紹如何實現乙個多執行緒的python爬蟲來提高抓取網頁的效率。

很多人都說因為python的gil (gil規定每個時刻只能有乙個執行緒訪問python虛擬機器)限制,不應該用多執行緒,而應該用多程序。首先,這個觀點是大錯特錯的!如果是乙個io密集型的任務,多執行緒肯定是work的。所謂io密集型任務,例如:網路互動,檔案的讀寫。這些不依賴cpu的操作我們是可以通過使用多執行緒來大大提高程式的效率。

python一般通過threading庫來實現多執行緒。threading庫是對thread庫進行包裝後的產物。

1. 我們可以通過繼承threading當中的thread類。

2. 然後再init裡呼叫thread的init方法(或者用super呼叫超類的建構函式),就可以完成對乙個執行緒的初始化建立工作。

3. 然後我們可以通過重寫類的run方法來定義這個執行緒的要做的事。

4. 建立乙個這個類的物件。

5. 然後呼叫這個物件的start方法就讓這個執行緒開始工作了。

6. 呼叫物件的join方法等待這個執行緒結束工作。

對照著下面**看相信你會更深刻的理解這個過程。

from threading import thread

class mythread(thread):

def __init__(self):

thread.__init__(self)

#super(mythread, self).__init__()

def run(self):

#write this thread task

pass

if __name__ == '__main__':

thread = mythread()

thread.start()

thread.join()

有過相關執行緒程式設計經驗的人都知道一般當多個執行緒共用一些資料的時候,我們就需要對這些執行緒進行同步,避免多個程序同時修改這些共用資料的時候產生錯誤。試想:乙個執行緒的工作是將乙個數加一,另乙個執行緒的工作是將這個數減一,假設這個數初始值是1,那麼當這兩個執行緒同時要對這個數操作,結果呢?結果是不可預知的。因為他們對這個數的操作產生了衝突,而計算機是沒法避免這種衝突的。所以我們要在寫程式的時候就解決這種可能的錯誤,我們該怎麼辦呢?

上鎖!所謂上鎖,就是當乙個執行緒要操作這個資料之前,把通向這個資料的「門」鎖上(也就是禁止了其他語句訪問這個資料),然後執行該執行的操作,當這些操作完成了,離開的時候把這個「門」再開啟。當門鎖上的時候,假如別的執行緒要操作這個資料,它就會被告知,這門裡有人了,你先等著,直到其他執行緒操作完了,門再次開啟以後,它才會繼續原本的操作。

python的queue庫,提供了執行緒同步機制(這個機制就類似上面說的上鎖的這個流程),我們可以直接使用queue輕鬆實現多執行緒同步。

乙個簡單的執行緒同步問題,我們通常可以稱之為生產者,消費者的問題。生產者負責產生資料,消費者負責對這些資料處理(消費資料),這兩個「者」在程式中就可以表示為兩個執行緒。如果使用queue,那麼就是,生產者將資料放入到queue中,消費者從queue中讀取資料。queue是一種先進先出的資料結構,一般來說讀資料都從queue頭讀,寫資料都從queue尾寫入,所以queue非常適合在這種情況下儲存資料。

下面這段**將簡單的表示如何使用python中的queue庫,來解決乙個簡單的生產者,消費者的問題。

from threading import thread

from queue import queue

global my_queue

my_queue = queue()

class mythread1(thread):

def __init__(self):

thread.__init__(self)

#super(mythread1, self).__init__()

def run(self):

put_data = "you producer data"

my_queue.put(put_data)

#write this thread task

pass

class mythread2(thread):

def __init__(self):

thread.__init__(self)

#super(mythread2, self).__init__()

def run(self):

get_data = my_queue.get()

#write this thread task

pass

if __name__ == '__main__':

thread1 = mythread1()

thread2 = mythread2()

thread1.start()

thread2.start()

thread1.join()

thread2.join()

基於上述關於執行緒的基礎知識和強大的python庫,我已經修改了上篇的爬蟲**,增加了多執行緒功能,大大加快了抓取速度。

2. 處理

io密集型任務時,我們得通過嘗試來確定執行緒的數量。因為限制因素有時候是網路速度,有時候是檔案io,也有時候就是電腦效能的瓶頸了(

執行緒數過多時,切換執行緒所消的時間甚至會超過實際工作時間)。

原文發於部落格

:gmx 2015.10.26  us  pacific time

python爬蟲 多執行緒爬蟲

在進行爬蟲工作的時候,考慮到爬蟲執行的速度慢,那麼怎樣提公升爬蟲的速度呢,那麼就得使用多執行緒爬蟲了,接下來我以糗事百科段子的爬取進行對多執行緒爬蟲的概述 github鏈結 鏈結一 不使用多執行緒爬取糗事百科 1.上 import urllib.request import re headers f...

python多執行緒爬蟲

先記錄一下,普通的糗事百科爬蟲 import urllib.request import re import time import urllib.error headers user agent mozilla 5.0 windows nt 10.0 win64 x64 rv 63.0 gecko...

python多執行緒爬蟲

python多執行緒爬蟲 python單執行緒爬蟲對於應付小規模資料是可以的,但是面對大量資料,我們就要用到多執行緒爬蟲技術。使用多執行緒,一方面可能會加快效率,另一方面可以施加一些小技巧,如不同的執行緒使用不同的 ip從而避免出發反爬機制。python 多執行緒 python的多執行緒可以用thr...