跳到主要內容

發表文章

目前顯示的是 9月, 2020的文章

Python 網絡爬蟲實戰:爬取 B站《全職高手》20萬條評論數據

本周我們的目標是:B站(嗶哩嗶哩彈幕網 https://www.bilibili.com )視頻評論數據。 我們都知道,B站有很多號稱"鎮站之寶"的視頻,擁有着數量極其恐怖的評論和彈幕。所以這次我們的目標就是,爬取B站視頻的評論數據,分析其為何會深受大家喜愛。 首先去調研一下,B站評論數量最多的視頻是哪一個。。。好在已經有大佬已經統計過了,我們來看一哈! ​【B站大數據可視化】B站評論數最多的視頻究竟是?來自 <https://www.bilibili.com/video/av34900167/>   嗯?《全職高手》,有點意思,第一集和最後一集分別佔據了評論數量排行榜的第二名和第一名,遠超了其他很多很火的番。那好,就拿它下手吧,看看它到底強在哪兒。 廢話不多說,先去B站看看這部神劇到底有多好看 https://www.bilibili.com/bangumi/play/ep107656 ​ 額,需要開通大會員才能觀看。。。 好吧,不看就不看,不過好在雖然視頻看不了,評論卻是可以看的。 ​ 感受到它的恐怖了嗎?63w6條的評論!9千多頁!果然是不同凡響啊。 接下來,我們就開始編寫爬蟲,爬取這些數據吧。   使用爬蟲爬取網頁一般分為四個階段:分析目標網頁,獲取網頁內容,提取關鍵信息,輸出保存。 1. 分析目標網頁 首先觀察評論區結構,發現評論區為鼠標點擊翻頁形式,共 9399 頁,每一頁有 20 條評論,每條評論中包含 用戶名、評論內容、評論樓層、時間日期、點贊數等信息展示。 ​ 接着我們按 F12 召喚出開發者工具,切換到Network。然後用鼠標點擊評論翻頁,觀察這個過程有什麼變化,並以此來制定我們的爬取策略。 我們不難發現,整個過程中 URL 不變,說明評論區翻頁不是通過 URL 控制。而在每翻一頁的時候,網頁會向服務器發出這樣的請求(請看 Request URL)。 ​ 點擊 Preview 欄,可以切換到預覽頁面,也就是說,可以看到這個請求返回的結果是什麼。下面是該請求返回的 json 文件,包含了在 replies 里包含了本頁的評論數據。在這個 json 文件里,我們可以發現,這裏面包含了...

tarjan算法求scc & 縮點

前置知識 圖的遍歷(dfs) 強連通&強連通分量 對於 有向圖 G中的任意兩個頂點u和v存在u->v的一條路徑,同時也存在v->u的路徑,我們則稱這兩個頂點強連通。以此類推,強連通分量就是某一個分量內各個頂點之間互相連通。 簡單來說,就是有向圖內的一個分量,其中的任意兩個點之家可以互相到達。 求有向圖內部強連通分量的方法大概有2種:tarjan算法,korasaju算法。這裏我們只對tarjan算法進行討論。 tarjan算法 tarjan算法是tarjan神仙提出的基於dfs時間戳和堆棧的算法,這裏我們可以先來看一下什麼是dfs時間戳 dfs時間戳 dfs時間戳就是dfs的先後順序,詳細來講,比如我們dfs最先訪問到的節點是A,於是A的時間戳就是1,第二個訪問到的節點是E,那麼E的時間戳就是2,我們用 \(dfn[u]\) 來表示u節點的時間戳,應該算是比較簡單的 算法步驟 首先,除了dfn以外我們還需要一個low數組,這個數組記錄了某個點通過圖上的邊能回溯到的dfn值最小的節點。這句話相信在大多數博客裏面都有提到,這裏我們來看一個簡單的例子: 首先,我們有一個圖G: 假設我們從a點出發開始dfs,我們可以畫出一個dfs樹: 為什麼我們畫出來的dfs樹和原來的圖不一樣呢?因為我們在dfs的過程中實際上是會忽略某一些連接到已訪問節點的邊的,這些邊我們暫且稱之為回邊。對於點u來說, \(low[u]\) 保存的就是點u通過某一條(或者是幾條)回邊能到達的dfn值最小的節點(也就是被最先訪問的節點)。假設這個dfn值最小的節點是u',我們可以知道,因為u和u'都是在一棵dfs樹上的,並且u'可以到達u,同時u可以通過一條或多條回邊到達u',也就是說u'->u路徑上的任意節點都可以通過這一條回邊來互相到達,也就是說他們會形成一個強連通分量。 更加詳細的例子 我們有一個新圖G: 假設我們從A點出發開始dfs,一路跑到D點,那麼我們為這個圖上的每一個點加上dfn數組和low數組的值(dfn,low),整個圖就會長成這個樣子: 此時我們會遇到一條D->A的回邊,也就是說點D能訪問到的dfn值最小的節點從點D本身變化到了A...

12.DRF-節流

Django rest framework源碼分析(3)----節流 添加節流 自定義節流的方法 限制60s內只能訪問3次 (1)API文件夾下面新建throttle.py,代碼如下: # utils/throttle.py from rest_framework.throttling import BaseThrottle import time VISIT_RECORD = {} #保存訪問記錄 class VisitThrottle(BaseThrottle): '''60s內只能訪問3次''' def __init__(self): self.history = None #初始化訪問記錄 def allow_request(self,request,view): #獲取用戶ip (get_ident) remote_addr = self.get_ident(request) ctime = time.time() #如果當前IP不在訪問記錄裏面,就添加到記錄 if remote_addr not in VISIT_RECORD: VISIT_RECORD[remote_addr] = [ctime,] #鍵值對的形式保存 return True #True表示可以訪問 #獲取當前ip的歷史訪問記錄 history = VISIT_RECORD.get(remote_addr) #初始化訪問記錄 self.history = history #如果有歷史訪問記錄,並且最早一次的訪問記錄離當前時間超過60s,就刪除最早的那個訪問記錄, #只要為True,就一直循環刪除最早的一次訪問記錄 while history and history[-1] < ctime - 60: history.pop() ...