亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么用一行代碼讓gevent爬蟲提速100%

發布時間:2021-10-29 17:44:32 來源:億速云 閱讀:146 作者:iii 欄目:編程語言

這篇文章主要介紹“怎么用一行代碼讓gevent爬蟲提速100%”,在日常操作中,相信很多人在怎么用一行代碼讓gevent爬蟲提速100%問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么用一行代碼讓gevent爬蟲提速100%”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

用python做網絡開發的人估計都聽說過gevent這個庫,gevent是一個第三方的python協程庫,其是在微線程庫greenlet的基礎上構建而成,并且使用了epoll事件監聽機制,這讓gevent具有很好的性能并且比greenlet更好用。gevent具有以下特點:

  1.  基于libev或libuv的快速事件循環。

  2.  基于greenlet的輕量級執行單元。

  3.  重復使用Python標準庫中的概念的API(例如,有event和 queues)。

  4.  具有SSL支持的協作套接字

  5.  通過線程池,dnspython或c-ares執行的合作DNS查詢。

  6.  猴子修補實用程序,使第三方模塊能夠合作

  7.  TCP / UDP / HTTP服務器

  8.  子流程支持(通過gevent.subprocess)

  9.  線程池

筆者總結一下,gevent大致原理就是當一個greenlet遇到需要等待的操作時(多為IO操作),比如網絡IO/睡眠等待,這時就會自動切換到其他的greenlet,等上述操作完成后,再在適當的時候切換回來繼續執行。在這個過程中其實仍然只有一個線程在執行,但因為我們在等待某些IO操作時,切換到了其他操作,避免了無用的等待,這就為我們大大節省了時間,提高了效率。

筆者也是在看了gevent這么多的優點之后,感覺有必要上手試一試,但起初效果非常不理想,速度提升并不大,后來在仔細研究了gevent的用法之后,發現gevent的高效率是有條件的,而其中一個重要條件就是monkey patch的使用,也就是我們常說的猴子補丁。

monkey patch就是在不改變源代碼的情況下,對程序進行更改和優化,其主要適用于動態語言。通過monkey patch,gevent替換了標準庫里面大部分的阻塞式系統調用,比如socket、ssl、threading和select等,而變為協作式運行。下面筆者還是通過代碼來演示一下monkey patch的用法以及使用條件。筆者展示的這個程序是一個小型的爬蟲程序,程序代碼量少,便于閱讀和運行,同時也能較好地測試出monkey patch的提升程度。主要思路是從Box Office Mojo網站抓取北美電影市場今年第二季度上映的電影,然后從每部電影的信息頁面提取出每部電影的電影分級,然后把每部電影的名稱和其對應分級保存在一個字典當中,再測試一下整個過程的時間。在這里,我們主要測試三種情況下的程序完成時間,分別是普通不使用gevent的爬蟲,使用gevent但不用monkey patch的爬蟲,以及使用gevent和monkey patch的爬蟲。

首先看普通不使用gevent的爬蟲。

先導入需要的庫。

import time  import requests  from lxml import etree

然后讀取第二季度上映電影的頁面。

url = r'https://www.boxofficemojo.com/quarter/q2/2020/?grossesOption=totalGrosses' #第二季度上映電影的網址  headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'} #爬蟲頭部  rsp = requests.get(url, headersheaders=headers) #讀取網頁  text = rsp.text #獲取網頁源碼  html = etree.HTML(text)  movie_relative_urls =  html.xpath(r'//td[@class="a-text-left mojo-field-type-release mojo-cell-wide"]/a/@href') #獲取每部電影的信息頁面的相對地址  movie_urls = [r'https://www.boxofficemojo.com'+u for u in movie_relative_urls] #把每部電影的相對地址換成絕對地址  genres_dict = {} #用于保存信息的字典

上述代碼中變量url就是第二季度上映電影的網頁地址,其頁面截圖如圖1所示。headers是爬蟲模擬瀏覽器的頭部信息,每部電影的信息頁面就是圖1中表格頭一行列名Release下面每部電影名稱所包含的網址,點擊每部電影名稱就可進入其對應頁面。因為這個網址是相對地址,所以要轉換成絕對地址。

怎么用一行代碼讓gevent爬蟲提速100%

圖1. 第二季度上映電影的頁面

接下來是每部電影的信息頁面的讀取。

def spider(url): #這個函數主要用于讀取每部電影頁面中的電影分級信息      rsp = requests.get(url, headersheaders=headers) #讀取每部電影的網頁      text = rsp.text #獲取頁面代碼      html = etree.HTML(text)      genre = html.xpath(r'//div/span[text()="Genres"]/following-sibling::span[1]/text()')[0] #讀取電影分級信息      title = html.xpath(r'//div/h2/text()')[0] #讀取電影名稱  genres_dict[title] = genre #把每部電影的名稱和分級信息存入字典

這個函數就是為了讀取每部電影信息頁面的信息,其功能和上面讀取url頁面的功能類似,都非常簡單,沒有過多可說的。在每部電影頁面中,我們要讀取的每部電影的分級信息就在Genres這一行,比如圖2中電影The Wretched,其Genres信息就是Horror。

怎么用一行代碼讓gevent爬蟲提速100%

圖2. 示例電影信息頁面

接下來是時間測算。

normal_start = time.time() #程序開始時間  for u in movie_urls:      spider(u)  normal_end = time.time() #程序結束時間  normal_elapse = normal_end - normal_start #程序運行時間  print('The normal procedure costs %s seconds' % normal_elapse)

我們測算時間用time.time()方法,用結束時間減去開始時間就是程序運行時間,這里我們主要測試spider這個函數多次運行的時間。結果顯示,該過程耗時59.6188秒。

第二個爬蟲是使用gevent但不用monkey patch的爬蟲。其完整代碼如下。

import time  from lxml import etree  import gevent  import requests  url = r'https://www.boxofficemojo.com/quarter/q2/2020/?grossesOption=totalGrosses'  headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'}  rsp = requests.get(url, headersheaders=headers)  text = rsp.text  html = etree.HTML(text)  movie_relative_urls =  html.xpath(r'//td[@class="a-text-left mojo-field-type-release mojo-cell-wide"]/a/@href')  movie_urls = [r'https://www.boxofficemojo.com'+u for u in movie_relative_urls]  genres_dict = {}  task_list = [] #用于存放協程的列表  def spider(url):     rsp = requests.get(url, headersheaders=headers)      text = rsp.text      html = etree.HTML(text)      genre = html.xpath(r'//div/span[text()="Genres"]/following-sibling::span[1]/text()')[0]      title = html.xpath(r'//div/h2/text()')[0]      genres_dict[title] = genre    gevent_start = time.time()  for u in movie_urls:      task = gevent.spawn(spider, u) #生成協程      task_list.append(task) #把協程放入這個列表    gevent.joinall(task_list) #運行所有協程  gevent_end = time.time() gevent_elapse = gevent_end - gevent_start  print('The gevent spider costs %s seconds' % gevent_elapse)

這里絕大部分代碼和前面爬蟲代碼相同,但多了一個task_list變量,其是用于存放協程的列表,我們從gevent_start = time.time()這行開始看,因為前面的代碼都和之前的爬蟲相同。task = gevent.spawn(spider, u)是生成gevent中生成協程的方法,task_list.append(task)是把每個協程放入這個列表中,而gevent.joinall(task_list)就是運行所有協程。上面這些過程和我們運行多線程的方式非常相似。運行結果是59.1744秒。

最后一個爬蟲就是同時使用gevent和monkey patch的爬蟲,在這里筆者不再粘貼代碼,因為其代碼和第二個爬蟲幾乎一模一樣,只有一個區別,就是多了一行代碼from gevent import monkey; monkey.patch_all(),注意這是一行代碼,不過包含兩個語句,用分號放在了一起。最重要的是,這行代碼要放在所有代碼的前面,切記!!!

這個爬蟲的運行結果是26.9184秒。

筆者把這里三個爬蟲分別放在三個文件中,分別命名為normal_spider.py、gevent_spider_no.py和gevent_spider.py,分別表示普通不用gevent的爬蟲、使用gevent但不用monkey patch的爬蟲、使用gevent和monkey patch的爬蟲。這里有一點要注意,monkey patch暫不支持jupyter notebook,所以這三個程序要在命令行中使用,不能在notebook中使用。

最后把三種爬蟲的結果總結如下。

怎么用一行代碼讓gevent爬蟲提速100%

圖3. 三種爬蟲的結果對比

可以看出使用了gevent但不用monkey patch的爬蟲和普通爬蟲的運行時間幾乎完全相等,而在用了monkey patch以后,運行時間只有前面程序的一半不到,速度提升了大約120%,僅僅一行代碼就帶來如此大的速度提升,可見monkey patch的作用還是很大的。而對于前兩個爬蟲的速度幾乎完全一樣,筆者認為原因在于這兩個程序都是單線程運行,本質上沒有太大區別,同時網頁讀取數量較小(只有18個網頁),也很難看出gevent的效果。

到此,關于“怎么用一行代碼讓gevent爬蟲提速100%”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

色达县| 西乌珠穆沁旗| 怀化市| 新郑市| 肇州县| 东平县| 潼南县| 蕉岭县| 张家界市| 阿鲁科尔沁旗| 安达市| 类乌齐县| 晋宁县| 姜堰市| 贺兰县| 鹤山市| 通城县| 定州市| 团风县| 固原市| 泰州市| 株洲县| 仁布县| 临漳县| 新蔡县| 湘阴县| 兴义市| 永登县| 荥阳市| 乐平市| 京山县| 肇庆市| 平远县| 辉县市| 重庆市| 南溪县| 监利县| 凤台县| 新和县| 涟源市| 时尚|