三天學會用python進行簡單地爬取B站網頁視頻數據(一)

首先聲明,這並非是什麼教程文章,我就只是學了三天而已。我想把這三天學的過程,學到的東西和大家分享一下,以期拋磚引玉,僅此而已,如有錯誤,請指出,我會細心察看並改正。

先說一說,我在研習網頁爬蟲之前,所有的編程經驗均來自於本科時學習的C語言以及後來從事的項目(本科和碩士期間)中關於底層編程的經驗。所以我在此之前從未接觸過除C以外的高級語言和網頁編程的相關知識(Http和HTML我都分不清楚)。

為啥我要做這件事,原因有三:

  • 很閑很閑很閑,想學學python,現在不是全民人工智慧嗎?
  • 解決問題的過程或許不都是有趣的,但總比什麼都不幹要來的有趣的多。
  • 想從視頻數據的角度分析分析某up,看看有沒有啥特別的發現。

再說一說主要目的,也就是要解決什麼問題。我想要實現的是獲取某特定up主的所有視頻信息。為了完整地記錄我的學習過程,我把每一天所做的工作總結都寫在手機上的備忘錄中,所以接下來我會以此為大綱展開。

第一天

第一天我都幹了些什麼呢?第一天的備忘錄如下:

稍微琢磨了一下python

照葫蘆畫瓢寫了個爬取B站某一up所有視頻數據的小工具,B站有提供api,所以很方便,只需要找到所有視頻的aid就好了

統計結果很有趣,回來整理一下,寫成文章

嘗試用了一下requests,bs4和selenium三個包。兩者爬出來的html源碼不一樣。是因為requests只能爬靜態數據,selenium可以爬到動態數據嗎?感覺後者效率好低

深夜在床上總結一下一天的工作,睡覺

稍微琢磨了一下python,我先搭建了python的開發環境,並且用一些簡單程序嘗試了一下python的語法規範。這是學習一門新語言必要的兩個步驟。搭建開發環境,可以參考王樹義老師的文章與視頻:

blog.sciencenet.cn/blog

B站有提供api,這裡解釋一下api就是程序介面的意思。api是為了方便第三方程序開發者能快速的獲取網站或程序的必要信息而設立的介面。進入B站的api介面只需要訪問下面這個鏈接

視頻av170001的api

進入視頻av170001的api鏈接後,你就能看到如下的一些關於該視頻的基本信息:

{ "code":0, "data": { "aid":170001, "view":11748705, "danmaku":556419, "reply":69672, "favorite":340343, "coin":61905, "share":297281, "now_rank":0, "his_rank":13, "like":22064, "no_reprint":0, "copyright":2 }," message":"0","ttl":1}

比如播放數:11748705,評論數:69672,彈幕數:556419,等。但是沒有上傳時間,這個我之後會再說。也就是說,當已知一個視頻的aid之後,就可以通過api獲取該視頻的各項信息。那麼如果獲取一個up主所有視頻的aid就成了問題的關鍵。當然第一天,先嘗試一下解決簡單的問題,那麼就是已知aid獲取視頻的評論數。

想要解決這個簡單問題,需要用到兩個python的庫,requests和BeautifulSoup。requests用來向網頁發出請求,獲取網頁html源碼。這裡說一下什麼是html源碼,如果你現在按一下鍵盤的F12(多功能鍵盤請先按Fn再按F12),跳出來的一連串代碼就是html源碼。BeautifulSoup主要作用是將獲取的html源碼整合成可以閱讀的形式,BeautifulSoup會幫助轉變編碼格式從而使得可能出現的漢字不至於識別為亂碼。下面短短的這四句話就可以實現獲取可閱讀的html源碼:

DOWNLOAD_URL = http://api.bilibili.com/archive_stat/stat?aid= + strdata = requests.get(DOWNLOAD_URL).contentsoup = BeautifulSoup(data, "html.parser", from_encoding=utf-8)text = soup.get_text()

當下獲取的text就是在打開api鏈接里看到的文本。運行一下這四句話,我們可以看一看結果:

接下來的問題就變成了,如果獲得文本中reply後面的那一串數字。這裡我使用了python里的find()函數,如果鍵入text.find(reply)那麼該函數的返回值就是reply的首個字元r所在的位置。text是一個字元串結構,在python里也可以將其理解為一列字元,鍵入text[0],你會發現輸出的是text字元串的第一個字元:{。如果r所在的位置為num_r,那麼text[num_r ] = r,相應的text[num_r + 7] = 6,也就是我們想要的數字的最高位。reply後的這個數字的位置從num_r + 7開始到favorite前的逗號,截至,想找到這個逗號的位置,就用text.find(,"favorite")的返回值num_f即可。這樣的話我們就可以寫一個循環,來一位一位的獲取這個數字。

字元串位置與字元的關係

評論數獲取程序

同理,我們可以用相同的方法獲取播放數,彈幕數等等,這裡不再贅述。

接下來我們看一個關鍵的問題,即如何獲得某一up主的所有視頻的av號。正常來說,我們要想看某一up主的所有視屏,就會進入該up的主頁。嘗試看一下某up主頁的html源碼:

我們可以清楚的看到存在標籤<li data-aid = 20969362>,這個標籤就是為了從主頁連接到av20969362這個視頻的。那麼找到av號的思路很簡單,只需要下載好某up主頁的html源碼然後找到該標籤,並獲取data-aid後的數值即可。

思路確定後便開始嘗試,首先用request獲取html源碼。然而你會發現,request在這裡不好用了,剛剛還可以完整的獲取html源碼的requests現在只能獲取部分的源碼,而且我們想要的部分無法get。這時候需要用到在備註中提到的第三個庫selenium,selenium庫並不是python安裝時自帶的庫,需要自行安裝,如何安裝庫?請移步王樹義老師的文章:

blog.sciencenet.cn/blog

selenium庫是為了讓程序更好的偽裝成瀏覽器而設計的,其本質就是一個自動控制瀏覽器的工具。selenium庫支持3款瀏覽器,Firefox,Chrome,IE。如果想詳細了解,請移步百度,Google。我現在不求詳細了解,只要會用就好了。

path = "C:/Users/guanj/Documents/PythonEx/chromedriver_win32/chromedriver.exe" #Get Chromedriver.exe pathdriver = webdriver.Chrome(executable_path=path) #Drive Chromei = 1 s = str(i) # The current pageurl = "https://space.bilibili.com/10330740?from=search&seid=12264074931239145067#/video?tid=0&page="+s+"&keyword=&order=pubdate"#The homepage link for one upper whose uid is 10330740driver.get(url)#Load the urltime.sleep(5)#Delay 5s#Check out HTML entire page source codes for one pagepageSourceThree = driver.page_sourcePageSourceHtml = BeautifulSoup(pageSourceThree,"html.parser")PageSourceBodyHtml = PageSourceHtml.find(ul, attrs={class: list-list})#Find out the information of all videos under lable <ul> class = list-list

還是對照著程序比較好說啊。使用selenium爬取html源碼步驟如下(我這裡使用的是Chrome瀏覽器):

  1. 給定Chromedriver.exe所在路徑(selenium調用瀏覽器需要driver程序,在使用之前需要下載好Chromedriver.exe程序)
  2. 給定up主的主頁鏈接
  3. 載入主頁連接,並延時5s
  4. 通過find()函數從html源碼中尋找我們需要的標籤內容,html源碼就放在變數PageSourceBodyHtml中

運行一下該程序,看看是什麼結果:

找一找aid在哪裡?

為什麼要延時5s?

這些html源碼如何處理呢?

這是第二天的工作了。


推薦閱讀:

吾家B站初長成:一部中國在線視頻的少數派報告
95版後再無《神鵰》?當年的女神們李雨桐等人現在怎樣了?
《萬萬沒想到》第三季整體水平大幅度下滑?
如何理解暴走大事件最新一期中的短片《動物世界》?
B站是怎麼火起來的?

TAG:python爬蟲 | Python | 嗶哩嗶哩 |