爬蟲基本功就這?早知道干爬蟲了

文章分三個個部分

  1. 兩個爬蟲庫requests和selenium如何使用
  2. html解析庫BeautifulSoup如何使用
  3. 動態加載的網頁數據用requests怎麼抓

兩個爬蟲庫

requests

假設windows下安裝好了python和pip。
下面用pip安裝爬蟲庫requests

如果提示pip版本低,不建議升級,升級後可能python本身版本低,導致pip指令報錯。

進入Python命令行驗證requests庫是否能夠使用

看到import requests和requests.get函數都沒有報錯,說明安裝成功可以開發我們的第一個爬蟲程序了!
將代碼文件命名為test.py,用IDEL打開。

最簡單的爬蟲就這麼幾行!

  1. 引入requests庫,
  2. 用get函數訪問對應地址,
  3. 判定是否抓取成功的狀態,r.text打印出抓取的數據。

然後菜單欄點擊Run->Run Module 會彈出Python的命令行窗口,並且返回結果。我們訪問的是騰訊發佈新冠肺炎疫情的地址

如果沒有IDEL,直接cmd命令行運行按照下面執行

selenium

selenium庫會啟動瀏覽器,用瀏覽器訪問地址獲取數據。下面我們演示用selenium抓取網頁,並解析爬取的html數據中的信息。先安裝selenium

接下來安裝解析html需要的bs4和lxml。
安裝bs4

安裝lxml

要確保windows環境變量path的目錄下有chromedriver

我d盤的instantclient_12_2已經加到path里了。所以chromedriver解壓到這個目錄。chromedriver不同的版本對應Chrome瀏覽器的不同版本,開始我下載的chromedriver對應Chrome瀏覽器的版本是71-75(圖中最下面的),我的瀏覽器版本是80所以重新下載了一個才好使。
代碼如下

Python執行過程中會彈出

瀏覽器也自動啟動,訪問目標地址

IDEL打印結果如下

HTML解析庫BeautifulSoup

selenium例子中爬取數據後使用BeautifulSoup庫對html進行解析,提取了感興趣的部分。如果不解析,抓取的就是一整個html數據,有時也是xml數據,xml數據對標籤的解析和html是一樣的道理,兩者都是來區分數據的。這種格式的數據結構一個頁面一個樣子,解析起來很麻煩。BeautifulSoup提供了強大的解析功能,可以幫助我們省去不少麻煩。
使用之前安裝BeautifulSoup和lxml。
首先代碼要引入這個庫(參考上面selenium庫代碼)

from bs4 import BeautifulSoup  

然後,抓取

r = request.get(url)      
r.encoding='utf8'  
html=r.read() #urlopen獲取的內容都在html中  
mysoup=BeautifulSoup(html, 'lxml') #html的信息都在mysoup中了   

假設我們對html中的如下部分數據感興趣

<data>  
        <day>20200214</day>  
        <id>1</id>  
        <rank>11</rank>  
        <name>張三</name>  
    </data>  
    <data>  
        <day>20200214</day>  
        <id>4</id>  
        <rank>17</rank>  
        <name>李斯</name>  
    </data>  

首先要找到tag標籤為的數據,而這類數據不止一條,我們以兩條為例。那麼需要用到beautifulsoup的find_all函數,返回的結果應該是兩個數據。當處理每一個數據時,裏面的等標籤都是唯一的,這時使用find函數。

mysoup=BeautifulSoup(html, 'lxml')    
data_list=mysoup.find_all('data')  
for data in data_list:#list應該有兩個元素  
    day = data.find('day').get_text() #get_text是獲取字符串,可以用.string代替  
    id = data.find('id').get_text()  
    rank = data.find('rank').get_text()  
    name = data.find('name').get_text()  
    #print name  可以print測試解析結果  

這是beautifulsoup最簡單的用法,find和find_all不僅可以按照標籤的名字定位元素,還可以按照class,style等各種屬性,以及文本內容text作為條件來查找你感興趣的內容,非常強大。

requests庫如何抓取網頁的動態加載數據

還是以新冠肺炎的疫情統計網頁為例。本文開頭requests例子最後打印的結果裏面只有標題、欄目名稱之類的,沒有累計確診、累計死亡等等的數據。因為這個頁面的數據是動態加載上去的,不是靜態的html頁面。需要按照我上面寫的步驟來獲取數據,關鍵是獲得URL和對應參數formdata。下面以火狐瀏覽器講講如何獲得這兩個數據。
肺炎頁面右鍵,出現的菜單選擇檢查元素。

點擊上圖紅色箭頭網絡選項,然後刷新頁面。如下,

這裡會出現很多網絡傳輸記錄,觀察最右側紅框「大小」那列,這列表示這個http請求傳輸的數據量大小,動態加載的數據一般數據量會比其它頁面元素的傳輸大,119kb相比其它按位元組計算的算是很大的數據了,當然網頁的裝飾圖片有的也很大,這個需要按照文件類型那列來甄別。

url帶參數

然後點擊域名列對應那行,如下

可以在消息頭中看見請求網址,url的尾部問號後面已經把參數寫上了。
途中url解釋,name是disease_h5,callback是頁面回調函數,我們不需要有回調動作,所以設置為空,_對應的是時間戳(Python很容易獲得時間戳的),因為查詢肺炎患者數量和時間是緊密相關的。
我們如果使用帶參數的URL,那麼就用

url='網址/g2/getOnsInfo?name=disease_h5&callback=&_=%d'%int(stamp*1000)     
requests.get(url)   

url和參數分離

點擊參數可以看見url對應的參數

如果使用參數和url分離的形式那麼
那麼就這樣

url="網址/g2/getOnsInfo"  

formdata = {'name': 'disease_h5',   
'callback': '',   
'_': 當前時間戳    
}    

requests.get(url, formdata)  

找url和參數需要耐心分析,才能正確甄別url和參數的含義,進行正確的編程實現。參數是否可以空,是否可以硬編碼寫死,是否有特殊要求,比較依賴經驗。

總結

學完本文,閱讀爬蟲代碼就很容易了,所有代碼都是為了成功get到url做的準備以及抓到數據之後的解析而已。
有的url很簡單,返回一個.dat文件,裏面直接就是json格式的數據。有的需要設置大量參數,才能獲得,而且獲得的是html格式的,需要解析才能提取數據。
爬到的數據可以存入數據庫,寫入文件,也可以現抓現展示不存儲。

Tags: