文章分三個個部分
- 兩個爬蟲庫requests和selenium如何使用
- html解析庫BeautifulSoup如何使用
- 動態載入的網頁資料用requests怎麼抓
兩個爬蟲庫
requests
假設windows下安裝好了python和pip。
下面用pip安裝爬蟲庫requests
如果提示pip版本低,不建議升級,升級後可能python本身版本低,導致pip指令報錯。
進入Python命令列驗證requests庫是否能夠使用
看到import requests和requests.get函式都沒有報錯,說明安裝成功可以開發我們的第一個爬蟲程式了!
將程式碼檔案命名為test.py,用IDEL開啟。
最簡單的爬蟲就這麼幾行!
- 引入requests庫,
- 用get函式訪問對應地址,
- 判定是否抓取成功的狀態,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和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函式,返回的結果應該是兩個資料。當處理每一個資料時,裡面的
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格式的,需要解析才能提取資料。
爬到的資料可以存入資料庫,寫入檔案,也可以現抓現展示不儲存。