前言
學習Python爬蟲技術也是一件需要大量實踐的事情,因為并不是所有的網(wǎng)站都對爬蟲友好,更多的一種情況是網(wǎng)站為了限制爬蟲不得不在最小化影響用戶體驗的前提下對網(wǎng)站訪問做出一定的限制,最常見的就是一些網(wǎng)站的注冊和登錄頁面出現(xiàn)的驗證碼。
12306網(wǎng)站的驗證碼在很長一段時間內(nèi)飽受詬病,最初其復雜程度已經(jīng)影響到了用戶交互體驗,但是為什么12306沒有選擇為了用戶體驗而放棄驗證碼?因為驗證碼就像是一個門檻,它主要針對的并不是人,而是可能含有惡意的計算機程序。12306網(wǎng)站堪稱掌握地表最強開發(fā)和維護技術,它每天運行的服務器壓力幾乎都等同于雙十一,高峰時段的操作壓力甚至遠超雙十一十幾倍。這是個提供剛需服務的網(wǎng)站,穩(wěn)定的重要性在一定程度上是大于用戶體驗的,如果沒有驗證碼,那么程序就可以輕而易舉的執(zhí)行登錄、注冊等操作。像我上一篇文章中提到的自動搶票軟件,刷新訪問的頻率越高,對12306服務器的壓力就越大。12306也不能分辨屏幕前坐著的到底是不是人,所以只能采取最簡單粗暴的人機識別方法:驗證碼。
扯遠了,不過這也是我們后續(xù)會遇到的反爬蟲手段之一。
既然是爬蟲,當然還是要先確認目標網(wǎng)站,這里推薦一個我認為非常不錯的爬蟲練習網(wǎng)站:鍍金的天空
這個網(wǎng)站中從易到難列出了8中反爬蟲的挑戰(zhàn),今天要講的就是其中的基礎1:爬取單頁數(shù)據(jù)并計算數(shù)據(jù)和
按下f12調(diào)出開發(fā)者工具選擇我們需要操作的數(shù)據(jù),注意這里需要我們記錄下數(shù)據(jù)在html文件中的特征
它是在一個名為col-md-1的div下的數(shù),這個特征為我們之后的數(shù)據(jù)提取提供了依據(jù)。可能有的小伙伴不太懂html代碼,這里簡單提一下html語法的一些特性:
這些內(nèi)容還是需要去仔細的了解一下,本系列的文章基本不會再對html基礎方向的問題進行敘述。
程序實現(xiàn)與基礎系列不同,為了尊重站長意愿,同時也為了大家能夠更好的上手實踐,涉及到glidedsky的文章將不會給出全部代碼,但是會盡量講清楚所涉及到的技術和部分代碼。
Python獲取網(wǎng)頁文本網(wǎng)頁訪問分GET/POST/DELETE/PUT/OPTION幾種不同的類型,最常用的是GET和POST請求。get請求的特點是所有參數(shù)及數(shù)據(jù)都顯示在URL鏈接中,主要用于獲取數(shù)據(jù),對數(shù)據(jù)本身并不執(zhí)行操作,所以我們寫爬蟲的過程中遇到比較多的還是get請求。POST請求主要用于向服務器傳入數(shù)據(jù),POST請求的內(nèi)容在瀏覽器頁面上是不顯示的,需要借助網(wǎng)頁抓包工具。chrome瀏覽器的f12開發(fā)者工具可以查看到post請求及其內(nèi)容
使用burpsuite抓包也可以獲取到POST數(shù)據(jù)包的內(nèi)容
一個請求包通常由請求頭和請求主體構成,在這個請求包中,除了POST表單數(shù)據(jù)之外的數(shù)據(jù)都是請求頭。這里面的數(shù)據(jù)主要用于和服務器交互,驗證數(shù)據(jù)來源及登錄憑證。
首先就是藍框標注的數(shù)據(jù)包類型為POST,后一個參數(shù)為處理該請求的文件名。然后黃框下有幾個屬性在寫爬蟲時需要用到,首先是User-Agent代表訪問設備信息和瀏覽器基本信息。
Cookie,這個屬性下保存的信息可以相當于一個憑證,任何人拿到你在這個網(wǎng)站的cookie都可以在不知道你的賬號密碼的情況下進入登錄狀態(tài)。
在Python中要實現(xiàn)網(wǎng)頁訪問功能有很多種方法,我比較喜歡使用requrests這個庫。
使用requests中的get方法完成get請求
注:如果報了這種錯誤:
則說明你的電腦中沒有安裝requests庫,在命令行中使用pip install requests命令可進行安裝。
可以看到程序成功返回了網(wǎng)頁源碼,但是仔細看會發(fā)現(xiàn)使用Python獲取到的源碼中并沒有包含我們想要的數(shù)據(jù)。
這是因為該網(wǎng)站做了限制,只有登錄后才可以看到數(shù)據(jù),所以在請求時我們必須帶上cookie才可以。
按下f12,點擊network網(wǎng)絡選項,找到主要請求的網(wǎng)頁,將cookie后的內(nèi)容全部復制下來。
requests的get()方法允許我們傳入一個header參數(shù)
成功獲取到目標數(shù)據(jù)
處理獲取到的文本數(shù)據(jù)接下來先理下思路:目的:提取所有數(shù)字并求和現(xiàn)已完成:獲取到全部文本接下來要做的:
確實就是這么樸實無華,想要從這么長的文本中準確獲取到數(shù)值,我們需要用到兩個庫:BeautifulSoup和re
BeautifulSoup屬于外部庫,需要在命令行中使用pip install BeautifulSoup4進行安裝。
引入方法:
from bs4 import BeautifulSoup
re為正則表達式支持庫,Python自帶,但是同樣需要使用import引入
Beautiful Soup 是一個可以從HTML或XML文件中提取數(shù)據(jù)的Python庫.它能夠通過你喜歡的轉換器實現(xiàn)慣用的文檔導航,查找,修改文檔的方式。
這是官方的解釋,通俗點說就是它可以幫助你更方便的提取數(shù)據(jù)。
正則表達式是用來匹配具有某種特征數(shù)據(jù)的模式,它定義了一些字符代表不同的數(shù)據(jù)。
雖然普通人真正見到正則表達式本體的機會不多,但是肯定都用過。
例如在注冊一個網(wǎng)站時,會要求你填寫郵箱和手機號,程序就是通過正則表達式首先判斷你輸入的郵箱和手機號格式是否正確。
正則表達式語法同樣比較復雜,但是非常有效,非常建議學習。
推薦看這篇文章了解正則表達式: 三十分鐘入門正則表達式
理解這兩個庫的作用之后我們就可以開始使用它們了。
首先使用BeautifulSoup對獲取到的網(wǎng)頁內(nèi)容進行處理
soup = BeautifulSoup(html,'html.parser')
在處理后的數(shù)據(jù)中提取出所有class=col-md-1的div的內(nèi)容
nums = soup.find_all('div',class_='col-md-1')
此是我們的數(shù)據(jù)變?yōu)椋?/p>
注意這里我圈出的細節(jié),這說明經(jīng)過處理后的數(shù)據(jù)存儲到了一個列表中。
接下來就是需要把除了數(shù)字之外的字符全部剔除
x = re.findall(r'\d\d\d',str(nums),re.DOTALL)
因為正則表達式是針對字符串的,所以我們需要用str方法將剛獲取到的數(shù)據(jù)轉化為字符串類型,findall方法的第一個參數(shù)即是匹配三位數(shù)字的正則表達式,re.DOTALL表示匹配所有字符,包括換行符等特殊符號。
re模塊中的Findall方法,和BeautifulSoup模塊的find_all方法完全不一樣。
Python re模塊的官方文檔中詳細羅列了各個方法的使用方法和一些簡單的正則表達式知識。
至此,我們就已經(jīng)將所有的數(shù)值匹配出來了
接下來就可以使用for循環(huán)通過下標對這個列表進行遍歷,然后將數(shù)據(jù)累加求和,這部分的代碼不再給出。
多嘗試,三行代碼就能解決。
另外,其實BeautifulSoup和re任意一個模塊都可以完成數(shù)據(jù)篩選工作,我沒用的原因是因為我懶。
最后給出最終運行結果
聯(lián)系客服