我要偷偷的學Python,然後驚呆所有人(第七天)

qwer1030274531發表於2021-01-07

前一天說了,我們今天要進入到爬蟲的學習,對,今天我們開始爬

在這裡插入圖片描述

本系列文預設各位有一定的C或C++基礎,因為我是學了點C++的皮毛之後入手的Python,這裡也要感謝齊鋒學長送來的支援。
本系列文預設各位會百度,學習‘模組’這個模組的話,還是建議大家有自己的編輯器和編譯器的,上一篇已經給大家做了推薦啦?
我要的不多,點個關注就好啦
然後呢,本系列的目錄嘛,說實話我個人比較傾向於那兩本 Primer Plus,所以就跟著它們的目錄結構吧。
本系列也會著重培養各位的自主動手能力,畢竟我不可能把所有知識點都給你講到,所以自己解決需求的能力就尤為重要,所以我在文中埋得坑請不要把它們看成坑,那是我留給你們的鍛鍊機會,請各顯神通,自行解決。1234567

注:本文中黑色圖片來自“風變程式設計”

如果是小白的話,可以看一下下面這一段:

歡迎來到我們的圈子

我建了一個Python學習答疑群,有興趣的朋友可以瞭解一下: 這是個什麼群

直通群的傳送門: 傳送門


初見爬蟲

我和你們大部分人都一樣,首次自己玩爬蟲,以前都是被人爬的那種。
不過呢,我也不是啥大佬,所以也不會一上來就一大堆特別高大上的爬蟲技巧呈現出來,我們一步一步來吧。

網路爬蟲,也叫網路蜘蛛(Web Spider)。它根據網頁地址(URL)爬取網頁內容,而網頁地址(URL)就是我們在瀏覽器中輸入的網站連結。比如:,它就是一個URL。

為什麼是爬蟲

通用搜尋引擎的處理物件是網際網路網頁,目前網際網路網頁的數量已達百億,所以搜尋引擎首先面臨的問題是:如何能夠設計出高效的下載系統,以將如此海量的網頁資料傳送到本地,在本地形成網際網路網頁的映象備份。

網路爬蟲能夠起到這樣的作用,完成此項艱鉅的任務,它是搜尋引擎系統中很關鍵也很基礎的構件。

舉個很常見的栗子吧:百度。
百度這家公司會源源不斷地把千千萬萬個網站爬取下來,儲存在自己的伺服器上。你在百度搜尋的本質就是在它的伺服器上搜尋資訊,你搜尋到的結果是一些超連結,在超連結跳轉之後你就可以訪問其它網站了。

通用爬蟲架構

好,上面這張圖能看明白嗎?如果不能的話,我們來再看些使用者訪問網站的流程圖:

在這裡插入圖片描述

這是一個人機互動的流程,那麼我們再來看看爬蟲在這個閉環裡面能夠取代掉哪些工作:
在這裡插入圖片描述

是吧,非常符合我們的“人工智慧”的特性,解放我們的雙手。

爬蟲的工作步驟

第1步:獲取資料。爬蟲程式會根據我們提供的網址,向伺服器發起請求,然後返回資料。
第2步:解析資料。爬蟲程式會把伺服器返回的資料解析成我們能讀懂的格式。
第3步:提取資料。爬蟲程式再從中提取出我們需要的資料。
第4步:儲存資料。爬蟲程式把這些有用的資料儲存起來,便於你日後的使用和分析。1234567

這就是爬蟲的工作原理啦,無論之後的學習內容怎樣變化,其核心都是爬蟲原理。

本章旨在直截了當的認識爬蟲,所以過多的不必要的概念就不引伸了。

優秀爬蟲的特性

話說優秀的程式碼好像都是這些特性。
不過有人能說出優秀架構的特性嗎?讓我眼前一亮,驚呼一聲:“大佬,帶我”

1.高效能

這裡的效能主要是指爬蟲下載網頁的抓取速度,常見的評價方式是以爬蟲每秒能夠下載的網頁數量作為效能指標,單位時間能夠下載的網頁數量越多,爬蟲的效能越高。

要提高爬蟲的效能,在設計時程式訪問磁碟的操作方法( 磁碟IO)及具體實現時 資料結構的選擇很關鍵,比如對於待抓取URL佇列和已抓取URL佇列,因為URL數量非常大,不同實現方式效能表現迥異,所以高效的資料結構對於爬蟲效能影響很大。

2.可擴充套件性

即使單個爬蟲的效能很高,要將所有網頁都下載到本地,仍然需要相當長的時間週期,為了能夠儘可能縮短抓取週期,爬蟲系統應該有很好地可擴充套件性,即很容易透過增加抓取伺服器和爬蟲數量來達到此目的。

目前實用的大型網路爬蟲一定是分散式執行的,即多臺伺服器專做抓取。每臺伺服器部署多個爬蟲,每個爬蟲多執行緒執行,透過多種方式增加併發性。

對於巨型的搜尋引擎服務商來說,可能還要在全球範圍、不同地域分別部署資料中心,爬蟲也被分配到不同的資料中心,這樣對於提高爬蟲系統的整體效能是很有幫助的。

3.健壯性

爬蟲要訪問各種型別的網站伺服器,可能會遇到很多種非正常情況:比如網頁HTML編碼不規範、 被抓取伺服器突然當機,甚至爬到陷阱裡邊去了等。爬蟲對各種異常情況能否正確處理非常重要,否則可能會不定期停止工作,這是無法忍受的。

從另外一個角度來講,假設爬蟲程式在抓取過程中死掉,或者爬蟲所在的伺服器當機,健壯的爬蟲應能做到:再次啟動爬蟲時,能夠恢復之前抓取的內容和資料結構,而不是每次都需要把所有工作完全從頭做起,這也是爬蟲健壯性的一種體現。

4.友好性

爬蟲的友好性包含兩方面的含義:一是保護網站的部分私密性;另一是減少被抓取網站的網路負載。爬蟲抓取的物件是各型別的網站,對於網站所有者來說,有些內容並不希望被所有人搜到,所以需要設定協議,來告知爬蟲哪些內容是不允許抓取的。目前有兩種主流的方法可達到此目的:爬蟲禁抓協議和網頁禁抓標記。

這一點後面會再詳細說明。


爬蟲初體驗

網路爬蟲的第一步就是根據URL,獲取網頁的HTML資訊。在Python3中,可以使用urllib.request和requests進行網頁爬取。

 urllib庫是python內建的,無需我們額外安裝,只要安裝了Python就可以使用這個庫。
 requests庫是第三方庫,需要我們自己安裝。12

requests庫的基礎方法如下:
在這裡插入圖片描述

requests.get()

看一段虛擬碼:

import requests#引入requests庫res = requests.get('URL')#requests.get是在呼叫requests庫中的get()方法,#它向伺服器傳送了一個請求,括號裡的引數是你需要的資料所在的網址,然後伺服器對請求作出了響應。#我們把這個響應返回的結果賦值在變數res上。123456

剛剛我還在群裡跟他們說,學習Python最重要的是打基礎,從資料型別,資料結構開始。
那我們就來看看這爬蟲獲取資料的返回值是個什麼資料型別。

先隨便找個網址吧,要不就開頭那個小烏龜的網址吧:
http://photogz.photo.store.qq.com/psc?/V12wi4eb4HvNdv/ruAMsa53pVQWN7FLK88i5qLH0twfxCgrwzDJPH6IRZadTdk*QTPnqFYrVt5PNiU7vBOh1cvefk4UXqNZcMdzLWowRX1pF4GqWoBZ7YPq5AQ!/b&bo=eAFyAXgBcgERECc!

網址是長了點哈,不過可以實驗的。

import requests 
res = requests.get('URL') print(type(res))#列印變數res的資料型別1234

結果:<class ‘requests.models.Response’>

Response物件常用的四個屬性

在這裡插入圖片描述

首先是我們的status_code,它是一個很常用的屬性,用於檢查請求出否成功,可以把它的返回值列印出來看。
在這裡插入圖片描述

接著的屬性是response.content,它能把Response物件的內容以二進位制資料的形式返回,適用於圖片、音訊、影片的下載,看個例子你就懂了。
來我們把那個小烏龜爬下來,我放在我的QQ空間裡面的:

import requests
res = requests.get('http://photogz.photo.store.qq.com/psc?/V12wi4eb4HvNdv/ruAMsa53pVQWN7FLK88i5qLH0twfxCgrwzDJPH6IRZadTdk*QTPnqFYrVt5PNiU7vBOh1cvefk4UXqNZcMdzLWowRX1pF4GqWoBZ7YPq5AQ!/b&bo=eAFyAXgBcgERECc!')#發出請求,並把返回的結果放在變數res中pic=res.content#把Reponse物件的內容以二進位制資料的形式返回photo = open('烏龜.jpg','wb')#新建了一個檔案ppt.jpg,這裡的檔案沒加路徑,它會被儲存在程式執行的當前目錄下。#圖片內容需要以二進位制wb讀寫。你在學習open()函式時接觸過它。photo.write(pic)#獲取pic的二進位制內容photo.close()#關閉檔案123456789101112

大家也可以去爬一爬自己空間裡面的小照片。
有的朋友會問:那我要怎麼知道我的小照片網址呢?
其實也好辦:右擊小照片,新建標籤頁開啟,網址不就有了嗎。

再不行,你直接把這篇部落格上的小照片拖一下嘛,拖到新視窗去,網址就有了。

好,今天的實操大概就在這裡了。


講完了response.content,繼續看response.text,這個屬性可以把Response物件的內容以字串的形式返回,適用於文字、 網頁原始碼的下載。

看清楚啊,是原始碼。

來,隨便找個網址,比方說我這篇部落格的網址,我們來體驗一下:

import requests#引用requests庫res = requests.get(')novel=res.text#把Response物件的內容以字串的形式返回k = open('《第七天》.txt','a+')#建立一個名為《第七天》的txt文件,指標放在檔案末尾,追加內容k.write(novel)#寫進檔案中     k.close()#關閉文件1234567891011

接下來,我們看最後一個屬性:response.encoding,它能幫我們定義Response物件的編碼。

首先,目標資料本身是什麼編碼是未知的。用requests.get()傳送請求後,我們會取得一個Response物件,其中,requests庫會對資料的編碼型別做出自己的判斷。但是!這個判斷有可能準確,也可能不準確。

如果它判斷準確的話,我們列印出來的response.text的內容就是正常的、沒有亂碼的,那就用不到res.encoding;如果判斷不準確,就會出現一堆亂碼,那我們就可以去檢視目標資料的編碼,然後再用res.encoding把編碼定義成和目標資料一致的型別即可。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30239065/viewspace-2748142/,如需轉載,請註明出處,否則將追究法律責任。

相關文章