本次爬蟲項目將爬取豆瓣Top250電影的圖片,其網址爲:https://movie.douban.com/top250, 具體頁面以下圖所示:html
本次爬蟲項目將分別不使用多線程和使用多線程來完成,經過二者的對比,顯示出多線程在爬蟲項目中的巨大優點。本文所使用的多線程用到了concurrent.futures模塊,該模塊是Python中最廣爲使用的併發庫,它能夠很是方便地將任務並行化。在concurrent.futures模塊中,共有兩種併發模塊,分別以下:python
具體的關於該模塊的介紹能夠參考其官方網址:https://docs.python.org/3/library/concurrent.futures.html 。 本次爬蟲項目將會用到concurrent.futures模塊中的ThreadPoolExecutor類,多線程下載豆瓣Top250電影圖片。下面將會給出本次爬蟲項目分別不使用多線程和使用多線程的對比,以此來展現多線程在爬蟲中的巨大優點。web
首先,咱們不使用多線程來下載豆瓣Top250電影圖片,其完整的Python代碼以下:微信
import time import requests import urllib.request from bs4 import BeautifulSoup # 該函數用於下載圖片 # 傳入函數: 網頁的網址url def download_picture(url): # 獲取網頁的源代碼 r = requests.get(url) # 利用BeautifulSoup將獲取到的文本解析成HTML soup = BeautifulSoup(r.text, "lxml") # 獲取網頁中的電影圖片 content = soup.find('div', class_='article') images = content.find_all('img') # 獲取電影圖片的名稱和下載地址 picture_name_list = [image['alt'] for image in images] picture_link_list = [image['src'] for image in images] # 利用urllib.request..urlretrieve正式下載圖片 for picture_name, picture_link in zip(picture_name_list, picture_link_list): urllib.request.urlretrieve(picture_link, 'E://douban/%s.jpg' % picture_name) def main(): # 所有10個網頁 start_urls = ["https://movie.douban.com/top250"] for i in range(1, 10): start_urls.append("https://movie.douban.com/top250?start=%d&filter=" % (25 * i)) # 統計該爬蟲的消耗時間 t1 = time.time() print('*' * 50) for url in start_urls: download_picture(url) t2 = time.time() print('不使用多線程,總共耗時:%s'%(t2-t1)) print('*' * 50) main()
其輸出結果以下:多線程
************************************************** 不使用多線程,總共耗時:79.93260931968689 **************************************************
去E盤中的douban文件夾查看,以下圖:併發
咱們能夠看到,在不使用多線程的狀況下,這個爬蟲總共耗時約80s,完成了豆瓣Top250電影圖片的下載。app
接下來,咱們使用多線程來下載豆瓣Top250電影圖片,其完整的Python代碼以下:框架
import time import requests import urllib.request from bs4 import BeautifulSoup from concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETED # 該函數用於下載圖片 # 傳入函數: 網頁的網址url def download_picture(url): # 獲取網頁的源代碼 r = requests.get(url) # 利用BeautifulSoup將獲取到的文本解析成HTML soup = BeautifulSoup(r.text, "lxml") # 獲取網頁中的電影圖片 content = soup.find('div', class_='article') images = content.find_all('img') # 獲取電影圖片的名稱和下載地址 picture_name_list = [image['alt'] for image in images] picture_link_list = [image['src'] for image in images] # 利用urllib.request..urlretrieve正式下載圖片 for picture_name, picture_link in zip(picture_name_list, picture_link_list): urllib.request.urlretrieve(picture_link, 'E://douban/%s.jpg' % picture_name) def main(): # 所有10個網頁 start_urls = ["https://movie.douban.com/top250"] for i in range(1, 10): start_urls.append("https://movie.douban.com/top250?start=%d&filter=" % (25 * i)) # 統計該爬蟲的消耗時間 print('*' * 50) t3 = time.time() # 利用併發下載電影圖片 executor = ThreadPoolExecutor(max_workers=10) # 能夠本身調整max_workers,即線程的個數 # submit()的參數: 第一個爲函數, 以後爲該函數的傳入參數,容許有多個 future_tasks = [executor.submit(download_picture, url) for url in start_urls] # 等待全部的線程完成,才進入後續的執行 wait(future_tasks, return_when=ALL_COMPLETED) t4 = time.time() print('使用多線程,總共耗時:%s' % (t4 - t3)) print('*' * 50) main()
其輸出結果以下:函數
************************************************** 使用多線程,總共耗時:9.361606121063232 **************************************************
再去E盤中的douban文件夾查看,發現一樣也下載了250張電影圖片。url
經過上述兩個爬蟲程序的對比,咱們不難發現,一樣是下載豆瓣Top250電影,10個網頁中的圖片,在沒有使用多線程的狀況下,總共耗時約80s,而在使用多線程(10個線程)的狀況下,總共耗時約9.5秒,效率整整提升了約8倍。這樣的效率提高在爬蟲中無疑是使人興奮的。 但願讀者在看了本篇博客後,也能嘗試着在本身的爬蟲中使用多線程,說不定會有意外的驚喜哦~~由於,大名鼎鼎的Python爬蟲框架Scrapy,也是使用多線程來提高爬蟲速度的哦!
注意:本人現已開通兩個微信公衆號: 由於Python(微信號爲:python_math)以及輕鬆學會Python爬蟲(微信號爲:easy_web_scrape), 歡迎你們關注哦~~