當你看着你的博客的閱讀量慢慢增長的時候,心裏不由有了些小激動,可是不得不吐槽一下--博客園並不會顯示你的博客的總閱讀量是多少。而這一篇博客就將教你怎麼利用隊列這種結構來編寫爬蟲,最終獲取你的博客的總閱讀量。git
隊列是經常使用數據結構之一,在Python3中要用queue這個模塊來實現。queue這個模塊實現了三種隊列:github
class queue.Queue(maxsize=0):FIFO隊列(first in first out),先進先出,第一個進入隊列的元素會第一個從隊列中出來。maxsize用於設置隊列裏的元素總數,若小於等於0,則總數爲無限大。正則表達式
class queue.LifoQueue(maxsize=0):LIFO隊列(last in first out),後進先出,最後一個進入隊列的元素會第一個從隊列中出來。maxsize用於設置隊列裏的元素總數,若小於等於0,則總數爲無限大。數據結構
class queue.PriorityQueue(maxsize=0):優先級隊列(first in first out),給隊列中的元素分配一個數字標記其優先級。maxsize用於設置隊列裏的元素總數,若小於等於0,則總數爲無限大。app
此次我使用的是Queue這個隊列,Queue對象中包含的主要方法以下:ide
Queue.put(item, block=True, timeout=None):將元素放入到隊列中。block用於設置是否阻塞,若是timeout爲正數,代表最多阻塞多少秒。函數
Queue.get(block=True, timeout=None):從隊列中刪除並返回一個元素,若是隊列爲空,則報錯。block用於設置是否阻塞,若是timeout爲正數,代表最多阻塞多少秒。工具
Queue.empty():判斷隊列是否爲空,若是隊列爲空,返回False,不然返回True。
post
首先進入博客,而後打開開發者工具選擇查看元素,以下:url
這裏只要定位到類名爲postDesc的div節點就能夠提取到咱們想要的閱讀量信息了,這一步是很簡單的。問題在於如何實現翻頁?先定位到下一頁查看一下元素:
好像定位到id爲nav_next_page的div節點就好了,是這樣嗎?點擊進入下一頁,而後再次定位查看一下:
能夠看到用以前定位div節點的方法已經不行了,怎麼辦呢?個人解決辦法是用正則表達式進行匹配,由於下一頁對應的元素都是這樣的:
<a href="連接">下一頁</a>
因此只須要進行一下正則匹配就能獲取下一頁的連接了,若是獲取不到,就說明已是最後一頁了!
1 """ 2 Version: Python3.5 3 Author: OniOn 4 Site: http://www.cnblogs.com/TM0831/ 5 Time: 2019/3/11 10:46 6 """ 7 import re 8 import queue 9 import requests 10 from lxml import etree 11 12 13 class CrawlQueue: 14 def __init__(self): 15 """ 16 初始化 17 """ 18 self.q = queue.Queue() # 爬取隊列 19 self.username = input("請輸入您的博客名稱:") 20 self.q.put("http://www.cnblogs.com/" + self.username) 21 self.urls = ["http://www.cnblogs.com/" + self.username] # 記錄爬取過的url 22 self.result = [] # 儲存閱讀量數據 23 24 def request(self, url): 25 """ 26 發送請求和解析網頁 27 :param url: 連接 28 :return: 29 """ 30 res = requests.get(url) 31 et = etree.HTML(res.text) 32 lst = et.xpath('//*[@class="postDesc"]/text()') 33 for i in lst: 34 num = i.split(" ")[5].lstrip("閱讀(").rstrip(")") 35 self.result.append(int(num)) 36 37 # 下一頁 38 next_page = re.search('<a href="(.*?)">下一頁</a>', res.text) 39 if next_page: 40 href = next_page.group().split(' ')[-1].replace('<a href="', '').replace('">下一頁</a>', '') 41 if href not in self.urls: # 確保以前沒有爬過 42 self.q.put(href) 43 self.urls.append(href) 44 45 def get_url(self): 46 """ 47 從爬取隊列中取出url 48 :return: 49 """ 50 if not self.q.empty(): 51 url = self.q.get() 52 self.request(url) 53 54 def main(self): 55 """ 56 主函數 57 :return: 58 """ 59 while not self.q.empty(): 60 self.get_url() 61 62 63 if __name__ == '__main__': 64 crawl = CrawlQueue() 65 crawl.main() 66 print("您的博客總閱讀量爲:{}".format(sum(crawl.result)))
完整代碼已上傳到GitHub!