python手記(五):requests寫爬蟲(一):爬蟲簡介
上次將python的圖片處理庫簡單寫了下,也就基本處於玩的地步。哈哈,蠻嘲諷的,這次我嘗試著寫下爬蟲,有多深肯定是不敢保證的,畢竟能力有限。但是我會盡量去從原理上把爬蟲的東西說明白一些。讓大家有個直觀的認識,最後能自己寫出個簡單的定向小爬蟲,爬個小說,爬個圖片,爬首歌曲什麼的。
如果您爬蟲能力還不錯,那就不用再這幾篇文章上浪費時間了。如果您從未接觸過爬蟲,或者聽說過,但從未用過,那希望這幾篇文章對您有用,文章肯定不會寫的太長,預計在三四篇左右結束。把關於爬蟲的一些基本理論和應用盡量去闡述的明白些。
首先,爬蟲(spider)。從這個名字上我們就應該能想象出它的作用(以下內容為胡扯),“爬”,毋庸置疑就是動起來,體現的是爬蟲的“動態性”,就是你要自動地“爬”到各個地方,而不是讓我人工手動的給你指明方向。“蟲”,你能想到什麼,闊怕?不是,我想到的是“吃”。想想看,蟲子在一棵樹上亂爬,爬到哪就啃哪,吞下的東西就是你能得到的資料,而你要做的,就是把你精心“培育”的“spider”放到某棵你想要“吃”的樹上,看著它爬到這,爬到哪,這啃啃,那啃啃。
說的有點噁心了是不(笑),我們說回來。爬蟲,就是我們寫的段程式碼,我們把它比作一隻蜘蛛,那動態性就是它在一隻巨大的網上爬動,至於這張網,當然就是我們的網際網路,網路間的聯通,恰恰也就給予了爬蟲“動起來的基礎”。
說到這裡我們說下url,uniform resource locator。統一資源定位符,什麼意思?很好理解,就是告訴你資源放在什麼地方,簡單理解就是地址。我在另一個系列的文章中有寫這個東西,在這裡再簡單談下。url我們只要開啟網頁就已經使用了,當你開啟網頁的時候,你會看到圖片,看到文字,這些東西並不是存在你的計算機上,而是伺服器返回給你的。伺服器?在哪裡?
就是這個,在你的位址列中的這一串。其實當你開啟瀏覽器,瀏覽器所做的就是向“www.baidu.com”這個地址,也就是我們說的url傳送一個request請求。request當然可以有引數,就比如我們在某些網頁需要登入的那種,當點選登入,我們的request請求中就會包含使用者名稱,密碼之類的資料引數。一起傳送給對方的伺服器,當對方的伺服器接收到request請求,就會對你的請求進行處理,然後返回一個response迴應。就是說你開啟網頁看到的東西,就是你請求的伺服器,給你返回來的東西。
ok,這裡應該解釋清楚了,有的小夥伴看到了地址框裡的地址前有個http。http是一種協議,傳輸資料的一種方式,簡單理解。因為我也並不熟悉,怕誤人子弟。就是說我們通過http協議來傳輸的資料。
下面一項,我們拿我們的官網做例子。當我們去請求這個地址——https://www.csdn.net/時,瀏覽器給我們返回的就是:
就是我們的主介面了,那頁面是怎麼組成的呢?或者說展現在我們面前的這中格式啊,圖片啊,佈局啊究竟是怎樣展現出來的呢。
這裡就要說另一種語言HTML,相信玩web開發的朋友就很熟悉了。HyperText Markup Language,超文字標記語言。其實大部分瀏覽器都提供了檢視網頁原始碼的功能,只需要在網頁中單機滑鼠右鍵,選擇檢視原始碼就可以了。
我們檢視一下主頁的原始碼,就是這個。這裡簡單說下,我們可以看到他的主要框架就是:
<html>
<head>
something
</head>
<body>
something
</body>
</html>
主要分為兩部分head,和body。頭中的內容是一些說明性東西,這樣說可能並不準確。舉個例子吧,比如說這個網頁的編碼格式,網頁的title,佈局的樣式,某些處理方法,都可以寫在這裡面。當然,後面的兩項我們一般單一分開,分別寫成css,和js檔案,這就是我們寫網頁的三大利器了。css,Cascading Style Sheets層疊樣式表,主要就是我們樣式佈局等,比如頁面的排列啊顏色啊什麼的。js, java script。js和java的關係就像老婆和老婆餅的關係一下,沒啥關係哈。只是和名字而已,js中寫的是處理方法,比如我們前面說到登入,當你點選完後,由js指令碼進行處理。
記得有種說法,html是骨骼,css是衣服,js是血肉。最後展現在我們面前的就是個活生生的人了。我們再簡單來說下html,因為涉及到後面的東西,需要再深入點。我們說了head,其實網頁上顯示的內容在body中,我們看到的原始碼中都是這種結構<></>,這就形成了一對標籤,這也是html名字的由來。沒對標籤之間的內容,就是顯示的內容。
我們來看主頁原始碼這麼個例子,我們看到一排排<li></li>標籤,其實他和前面的<ul>標籤是一套東西,簡單理解下他的功能就是一個佈局,將一些東西放在一行行的<li>中,我們剛才說了,標籤內的東西,就是顯示的東西,但是我們看到的是另一個標籤<a></a>,這個標籤又是作甚的呢,超連結。也就是說當你點選這裡的時候,他就會跳轉到a標籤的地址中,a標籤有個屬性href,由它來指明跳轉的目標。兩個a標籤之間,就是顯示在頁面上的內容了,我們來看第一個,“最新文章”是網頁的顯示內容,他被a標籤框住,說明他在網頁上是個超連結,可以點選。之外又被li框住,說明是某個列表中的一列。
簡而言之,html就是網頁上要顯示的內容,我們有一堆的標籤來標記它們,從而讓他們有我們預期的模樣。圖片,也就是打了個<img>i標籤罷了。原理都是一樣的,我們返回到主頁,這一類東西,其實就是:
很簡單吧。
ok,我們的基礎內容就介紹完了,現在進入爬蟲的內容。我們寫爬蟲,就是模擬瀏覽器的過程,也是向某個url傳送請求,然後得到response,並從中拿到我們需要的東西。原理就是這樣。
在寫之前,還有一個重要的東西,爬蟲嘛,還是要接受一下規定,有人說這叫“盜亦有道”。哈,隨意怎樣理解吧,大部分網站呢,出於對使用者資訊保安,公司利益的考慮,有些東西是不允許你去爬的。
在每個網站的根目錄下,也就是網站的主頁面位置,會有個robots.txt檔案,裡面告訴你爬蟲所應遵守的規定。(你懂我“應”的意思吧。)
我們來看看我們的官網的robots:
在根目錄後面輸入robots.txt直接請求就可以。
這就是遵守協議了,我們來簡單看下,user-agent指明物件。*當然就是萬用字元,指所有人啦。Disallow不用解釋吧,就是不允許請求,我們看到後面的引數是一些分目錄,這些目錄都是網站不允許你去爬的,不是技術上的強制,而是法律道德的約束,懂我意思吧。
最後一行有個sitemap,它是給搜尋引擎指明什麼東西可以被搜尋,我們直接去訪問他:
看到so many連結,我們選第一個看看吧。
是一篇機器學習演算法的文章,那我們就用它來當我們的實驗物件好了。
文章題目也說明,我們用到的是requests這個module,不是標註庫,在dos命令列中pip install requests。就可以安裝了。接下來我們來看下怎樣得到這篇文章的原始碼吧。
import requests
'''
url = 'https://www.csdn.net/article/2018-10-15/2826812'
r = requests.get(url)
print(r.status_code)
with open('spider.txt', 'w') as f:
f.write(r.text)
'''
url = 'https://www.csdn.net/article/2018-10-15/2826812'
try:
r = requests.get(url)
r.raise_for_status()
r.encoding = r.apparent_encoding
print(r.headers)
with open('spider.txt', 'w') as f:
f.write(r.text)
except:
print('失敗')
首先匯入就不用說了,requests的get方法想指定地址傳送請求。requests的主要方法有七個,其實就一個requests.request()方法,其他的都是request方法延伸出來的。我們這裡只用最簡單的get。傳送請求後會返回response物件,物件的.status_code()方法可以檢視狀態碼。狀態碼如果是200,表示正常請求,你就可以繼續你的操作,如果不是,那就出錯了。最出名的應該就是我們常見的404,是不是瞬間就懂了。
r.encoding 是編碼格式,apparent_encoding也是,那有什麼區別呢,encoding是從response中直接獲取的,也就是說返回的說明性資料中告訴你charset是什麼,而apparent_encoding是程式根據網頁的內容分析出來的真實格式。如果response中沒告訴你,就會預設ISO-8859-1。
r.text就是返回的文字內容了,我們把它儲存在txt中。上下的程式碼功能是一樣的,下面的更規矩寫,只是多了raise_for_statue()方法,這個方法在狀態碼不是200的時候會丟擲異常。就是這點區別,期間輸出了headers,順便讓我們看下里面都有什麼:
第二行有個charset=utf-8,這個就是encoding了。
我們看下執行結果吧:
原始碼得到了,為什麼不在控制檯直接輸出,而是寫入檔案呢?因為資料過多,直接顯示會卡掉。
我們看到了,我們得到了全部的原始碼,但這並不是我們想要的,我們其實想要這部分:
大約在270行左右的文章內容,不要其他的。其實r.text得到的是string型別,之後的完全可以用字串去處理出你想要的資料。這個例子簡單些,因為要的資料都集中在一個地方,如果我想得到網頁中的全部url呢?這些東西可不是集中的,全部分散在不同地方,我要一個個找嗎。當然不用,這個我們放在下篇將,怎樣處理我們得到的網頁資料,需要另一個庫BuautifulSoup,不知道怎麼去翻哈,意會吧。
這個例子,可以直接用字串去處理哈,下篇文章我們再來看bs是怎麼處理的,你就能體會到它的重要性。
再見!