第一次接觸到python是一個很偶然的因素,因爲常常在網上看連載小說,不少小說都是上幾百的連載。所以想到能不能本身作一個工具自動下載這些小說,而後copy到電腦或者手機上,這樣在沒有網絡或者網絡信號很差的時候均可以看。當時還不知道網絡爬蟲的概念。工做學習中用得最多的是C編程,可是對於網絡世界而言,C確實不是一個好的語音,C更多面向硬件和內核。基於想本身下載網絡小說的念頭,認識到了python. 使用事後真是以爲是一門適合網絡的語言,加上數不清的第三方庫可使用。適合快速開發。固然python也在數據分析,天然語義方面也有不少優點。這裏主要介紹在網絡方面的應用。javascript
說到網絡,和咱們最接近的就是網頁了。網頁主要技術是http,固然還有javascript,XML,JSON,TCP鏈接等一大堆前端,後端的東東,關於http的知識這裏不作多的描述,推薦看下http權威指南。html
網頁都是用html語言寫的,關於HTML語言W3CSCHOOL上面有大量的介紹。而網絡爬蟲就是主要針對HTML語言而言。不以下面的百度的界面,用google瀏覽器點擊F12,IE右擊鼠標,而後選擇查看網頁源代碼。左邊是咱們上網看到的百度頁面,右邊就是html源代碼。被script包含的部分就是javascript。 這個頁面主要是動態加載的頁面,顯示的內容主要是用javascript來驅動。看上去還不太直觀。下面咱們看一個更簡單的前端
在百度一下上右擊鼠標,而後選擇審查元素,對於的HMTL代碼就顯示出來java
具體的代碼:能夠看到百度一下的這幾個字在input元素裏面,表明的是這是一個輸入框python
也許有人問,這和網絡爬蟲以及下載小說有啥關係,別急,前面的只是個網頁的入門介紹。下面咱們來看個小說的界面:下面是迅讀網的小說,左邊是小說正文,右邊是相關的網頁代碼。你們看到沒有,全部的小說正文都包含在標籤是<div>而且id=」content_1」的的元素裏面編程
若是咱們能有工具能自動將HTML代碼對應元素內容自動下載下來。不就能夠自動下載小說了。這就是網絡爬蟲的功能,說白了網絡爬蟲就是解析HMTL代碼並保存下來而後進行後處理的。簡單來講就三個步驟:1 解析網頁獲得數據,2 保存數據 3 數據的後處理。下面咱們就首先從第一步解析網頁獲得數據開始。windows
訪問網頁首先要請求URL,也就是網址連接。Python提供了urllib2函數進行連接。具體以下:後端
import urllib2
req=urllib2.Request('http://www.baidu.com.cn')
fd=urllib2.urlopen(req)
Request裏面的第一個參數爲網址的連接,裏面還能夠攜帶頭信息以及具體要傳遞給網址的信息。這樣說比較抽象。咱們用wireshark抓取一個上網的報文。在google瀏覽器中輸入www.sina.com.cn.能夠看到以下信息。這就是從電腦上發出去的請求。其中有幾個關鍵信息:Request Method: Get. 這裏有兩種方式,Get和Post,Get主要是用於請求數據,Post能夠用來提交數據。瀏覽器
User-Agent指的是用戶代碼,什麼意思呢。經過這些消息,服務器就可以識別客戶使用的操做系統以及瀏覽器。通常服務器能夠經過來識別是不是爬蟲。這個後面講服務器
Referer能夠認爲是你須要從服務器上請求什麼網址,這裏能夠看到就是sina
Accet-Encoding: 這是告訴電腦能夠接受的數據壓縮方式。
上圖是瀏覽器上輸入網址獲得的抓包結果。若是咱們運行程序結果會如何呢。下圖是剛纔python代碼的截圖結果。訪問的網址是百度。從下面能夠看到明顯的差異。最重要的就是User-Agent變成了Python-urllib2/2.7. 這個字段給服務器一個明確的提示,這是一個程序發起的網頁連接,也就是爬蟲,而不是坐在電腦前的人在訪問。因爲爬蟲進行連接同樣會進行TCP等底層連接,所以爲了防止大規模爬蟲同時進行網頁爬取。服務器會根據User-Agent來判斷,若是是爬蟲,則直接拒絕。
那麼爲了防止服務器禁掉咱們的申請,該如何應對呢。咱們自程序中本身構造一個和真實瀏覽器同樣的User_Agent不就同樣了。
user_agent="Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36"
headers={'User-Agent':user_agent}
req=urllib2.Request('http://www.baidu.com.cn','',headers)
fd=urllib2.urlopen(req)
添加了headers的描述。Request的第一個參數是網址,第二個參數是提交的數據,第三個參數是頭信息。這裏第二個參數暫時爲空。第三個參數添加頭信息,以字典的形式。能夠看到抓包信息以下。這裏就變成了咱們和瀏覽器同樣的形式,這樣服務器就不會認爲是爬蟲了。下一步就是放心的抓取網頁數據了。
有同窗可能會問,若是我不當心輸錯了網址,該怎麼辦呢。這就要用到python的異常保護機制了。代碼能夠修改以下:
try:
user_agent="Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36"
headers={'User-Agent':user_agent}
req=urllib2.Request('http://www.baidu.com.cn','',headers)
fd=urllib2.urlopen(req)
print fd.read().decode('utf-8').encode('GB18030')
html=BeautifulSoup(fd.read(),"lxml")
# print html.encode('gbk')
except urllib2.URLError,e:
print e.reason
增長了保護機制,其中URLError在沒有網絡鏈接或者服務器不存在的狀況下產生,這種狀況下,異常一般會帶有reason屬性.HTTP的錯誤碼以下,具體參考HTTP權威指南
200:請求成功 處理方式:得到響應的內容,進行處理
201:請求完成,結果是建立了新資源。新建立資源的URI可在響應的實體中獲得 處理方式:爬蟲中不會遇到
202:請求被接受,但處理還沒有完成 處理方式:阻塞等待
204:服務器端已經實現了請求,可是沒有返回新的信 息。若是客戶是用戶代理,則無須爲此更新自身的文檔視圖。 處理方式:丟棄
300:該狀態碼不被HTTP/1.0的應用程序直接使用, 只是做爲3XX類型迴應的默認解釋。存在多個可用的被請求資源。 處理方式:若程序中可以處理,則進行進一步處理,若是程序中不能處理,則丟棄
301:請求到的資源都會分配一個永久的URL,這樣就能夠在未來經過該URL來訪問此資源 處理方式:重定向到分配的URL
302:請求到的資源在一個不一樣的URL處臨時保存 處理方式:重定向到臨時的URL
304 請求的資源未更新 處理方式:丟棄
400 非法請求 處理方式:丟棄
401 未受權 處理方式:丟棄
403 禁止 處理方式:丟棄
404 沒有找到 處理方式:丟棄
5XX 迴應代碼以「5」開頭的狀態碼錶示服務器端發現本身出現錯誤,不能繼續執行請求 處理方式:丟棄
下面就是要打印出獲取到的網頁信息了。Request返回一個獲取網頁的實體,urlopen則是實現打開網頁fd.read()則能夠打印出網頁的具體信息
代碼裏面有這個decode和encode的消息。這個是幹嗎用的呢。這個主要是針對網頁中的中文。Python3以前的中文輸出是一個很憂傷的事情。
print fd.read().decode('utf-8').encode('GB18030')
網頁上的數據也有本身的編碼方式,從下面的截圖的網頁代碼看到編碼方式是utf-8.而在windows中中文的編碼方式是GBK。
所以若是不進行編碼轉換的話,網頁中的中文就會是亂碼形式:
那麼是否能夠提早獲取網頁的編碼方式呢,這也是能夠的。以下代碼就能夠獲得網頁返回的編碼方式
fd1=urllib2.urlopen(req).info()
print fd1.getparam('charset')
到此,咱們已經成功的進行網頁連接,並獲取到了網頁內容。下一步就是進行網頁解析了。後面講介紹beautifulSoup,lxml,HTMLParser,scrapy,selenium等經常使用的爬蟲工具用法