【Python3爬蟲】用Python中的隊列來寫爬蟲


一、寫在前面

當你看着你的博客的閱讀量慢慢增加的時候,內心不禁有了些小激動,但是不得不吐槽一下--博客園並不會顯示你的博客的總閱讀量是多少。而這一篇博客就將教你怎么利用隊列這種結構來編寫爬蟲,最終獲取你的博客的總閱讀量。

 

二、必備知識

隊列是常用數據結構之一,在Python3中要用queue這個模塊來實現。queue這個模塊實現了三種隊列:

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,則總數為無限大。

這次我使用的是Queue這個隊列,Queue對象中包含的主要方法如下:

Queue.put(item, block=True, timeout=None):將元素放入到隊列中。block用於設置是否阻塞,如果timeout為正數,表明最多阻塞多少秒。

Queue.get(block=True, timeout=None):從隊列中刪除並返回一個元素,如果隊列為空,則報錯。block用於設置是否阻塞,如果timeout為正數,表明最多阻塞多少秒。

Queue.empty():判斷隊列是否為空,如果隊列為空,返回False,否則返回True。

 

三、具體步驟

 首先進入博客,然后打開開發者工具選擇查看元素,如下:

這里只要定位到類名為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('&nbsp;')[-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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM