汪海爬虫学习笔记1
網絡爬蟲
網絡爬蟲就是一個爬行程序,一個抓取網頁的程序,有的人說抓取數據很簡單,但是管理爬蟲就很困難,現在我還不太明白,多學習以后就懂了。其實網絡爬蟲抓取網頁的過程和我們平時用瀏覽器登陸網頁的原理是一樣的,打開網頁的過程就是瀏覽器作為一個瀏覽的“客戶端”,向服務器端發送了?一次請求,把服務器端的文件“抓”到本地,再進行解釋、展現。瀏覽器的功能是將獲取到的HTML代碼進行解析,然后將原始的代碼轉變成我們直接看到的網站頁面。
URL是URI的子集,URL是Internet上描述信息資源的字符串,主要用在各種WWW客戶程序和服務器程序上。采用URL可以用一種統一的格式來描述各種信息資源,包括文件、服務器的地址和目錄等。爬蟲最主要的處理對象就是URL,它根據URL地址取得所需要的文件內容,然后對它?進行進一步的處理。因此,準確地理解URL對理解網絡爬蟲至關重要。
所謂網頁抓取,就是把URL地址中指定的網絡資源從網絡流中讀取出來,保存到本地。?
類似于使用程序模擬IE瀏覽器的功能,把URL作為HTTP請求的內容發送到服務器端,?然后讀取服務器端的響應資源。
入門的時候就可以拿python中的urllib2包來練練手,這個是python2中的包,在python3中就將其整合成一個包了,urllib2是Python的一個獲取URLs(Uniform?Resource?Locators)的組件。它以urlopen函數的形式提供了一個非常簡單的接口。
除了"http:",URL同樣可以使用"ftp:","file:"等等來替代。HTTP是基于請求和應答機制的:客戶端提出請求,服務端提供應答。
在HTTP請求時,允許你做額外的兩件事。
1.發送data表單數據
而發送數據有兩種方式分別是GET和POST,Get是向服務器發索取數據的一種請求,而Post是向服務器提交數據的一種請求。
有時候你希望發送一些數據到URL(通常URL與CGI[通用網關接口]腳本,或其他WEB應用程序掛接)。在HTTP中,這個經常使用熟知的POST請求發送。這個通常在你提交一個HTML表單時由你的瀏覽器來做。并不是所有的POSTs都來源于表單,你能夠使用POST提交任意的數據到你自己的程序。一般的HTML表單,data需要編碼成標準形式。然后做為data參數傳到Request對象。編碼工作使用urllib的函數而非urllib2。
如果沒有傳送data參數,urllib2使用GET方式的請求。GET和POST請求的不同之處是POST請求通常有"副作用",它們會由于某種途徑改變系統狀態(例如提交成堆垃圾到你的門口)。Data同樣可以通過在Get請求的URL本身上面編碼來傳送。
2.設置Headers到http請求
默認的urllib2把自己作為“Python-urllib/x.y”,有的網站卻不識別這個頭就拒絕其訪問,所以可以偽裝一下,模擬成瀏覽器去訪問,瀏覽器確認自己身份是通過User-Agent頭,當你創建了一個請求對象,你可以給他一個包含頭數據的字典。下面的例子發送跟上面一樣的內容,但把自身模擬成Internet?Explorer。
異常的處理
當urlopen不能夠處理一個response時,產生urlError。HTTPError是urlError的子類,通常在特定HTTP?URLs中產生。
1.URLError
通常,URLError在沒有網絡連接(沒有路由到特定服務器),或者服務器不存在的情況下產生。這種情況下,異常同樣會帶有"reason"屬性,它是一個tuple(可以理解為不可變的數組),包含了一個錯誤號和一個錯誤信息。
2.HTTPError
服務器上每一個HTTP?應答對象response包含一個數字"狀態碼"。有時狀態碼指出服務器無法完成請求。默認的處理器會為你處理一部分這種應答。例如:假如response是一個"重定向",需要客戶端從別的地址獲取文檔,urllib2將為你處理。其他不能處理的,urlopen會產生一個HTTPError。典型的錯誤包含"404"(頁面無法找到),"403"(請求禁止),和"401"(帶驗證請求)。HTTP狀態碼表示HTTP協議所返回的響應的狀態。比如客戶端向服務器發送請求,如果成功地獲得請求的資源,則返回的狀態碼為200,表示響應成功。如果請求的資源不存在,?則通常返回404錯誤。?HTTPError實例產生后會有一個整型'code'屬性,是服務器發送的相關錯誤號。因為默認的處理器處理了重定向(300以外號碼),并且100-299范圍的號碼指示成功,所以你只能看到400-599的錯誤號碼。
3.捕捉錯誤
所以如果你想為HTTPError或URLError做準備,將有兩個基本的辦法。
第一種就是使用try和except?Error來配合,先捕捉HTTPError,再捕獲URLError,分兩個except來捕捉,分別處理,一定要注意順序,因為HTTPError是URLError的子集。
而第二種方法同樣是try和except?Error來配合,但是只有一個except來捕獲,他通過hasattr()函數來確定這個錯誤是否有reason屬性和code屬性來分別判斷是什么錯誤,分別輸出。它是在一個except里面判斷錯誤的分類。
?
?
urlopen返回的應答對象response(或者HTTPError實例)有兩個很有用的方法info()和geturl()
1.geturl():
這個返回獲取的真實的URL,這個很有用,因為urlopen(或者opener對象使用的)或許會有重定向。獲取的URL或許跟請求URL不同。
2.info():
這個返回對象的字典對象,該字典描述了獲取的頁面情況。通常是服務器發送的特定頭headers。目前是httplib.HTTPMessage?實例。經典的headers包含"Content-length","Content-type",和其他內容。
Openers?and?Handlers還不是太明白,日后再補吧
?
#-*- coding:utf-8 -*- ''' #打開百度主頁,返回其網站的源代碼。 #urllib2是獲取URL的組件,urlopen可以用來打開網頁。 import urllib2 response = urllib2.urlopen('http://www.baidu.com') html = response.read() print html '''''' import urllib2 #網站去必須加http://或ftp://,不然會報錯,因為程序不識別。 #urllib2用一個Request對象來映射你提出的HTTP請求。 req = urllib2.Request('http://www.baidu.com') response = urllib2.urlopen(req) page = response.read() print page '''''' import urllib,urllib2 data = {'name':'www','password':'123456'} f = urllib2.urlopen(url='http://www.jb51.net/',data = urllib.urlencode(data)) print f.read() '''''' #POST發送數據到url import urllib import urllib2 url = 'http://www.someserver.com/register.cgi' values = {'name' : 'WHY', 'location' : 'SDU', 'language' : 'Python' } data = urllib.urlencode(values) # 編碼工作 req = urllib2.Request(url, data) # 發送請求同時傳data表單 response = urllib2.urlopen(req) #接受反饋的信息 the_page = response.read() #讀取反饋的內容 '''''' #GET方法發送data import urllib2 import urllibdata = {}data['name'] = 'WHY' data['location'] = 'SDU' data['language'] = 'Python'url_values = urllib.urlencode(data) print url_valuesname=Somebody+Here&language=Python&location=Northampton url = 'http://www.example.com/example.cgi' #GET通過?來分割網址和數據 full_url = url + '?' + url_valuesdata = urllib2.open(full_url) '''''' #更改自己的Headers,偽裝成瀏覽器去訪問 import urllib import urllib2 url = 'http://www.someserver.com/cgi-bin/register.cgi'user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' values = {'name' : 'WHY', 'location' : 'SDU', 'language' : 'Python' } headers = { 'User-Agent' : user_agent } data = urllib.urlencode(values)#Request一共三個參數,最后一個可以設置header req = urllib2.Request(url, data, headers) response = urllib2.urlopen(req) the_page = response.read() '''''' #URLError import urllib2 req = urllib2.Request('http://www.baibai.com')try:urllib2.urlopen(req)except urllib2.URLError , e:print e.reason '''''' #返回403錯誤 import urllib2 req = urllib2.Request('http://bbs.csdn.net/callmewhy')try:urllib2.urlopen(req)except urllib2.URLError, e:print e.code#print e.read() '''''' #捕獲HTTPError和URLError的第一種方法 from urllib2 import Request, urlopen, URLError, HTTPErrorreq = Request('http://bbs.csdn.net/callmewhy')try:response = urlopen(req)except HTTPError, e:print 'The server couldn\'t fulfill the request.'print 'Error code: ', e.codeexcept URLError, e:print 'We failed to reach a server.'print 'Reason: ', e.reasonelse:print 'No exception was raised.'# everything is fine '''''' #捕獲HTTPError和URLError的第二種方法 from urllib2 import Request, urlopen, URLError, HTTPErrorreq = Request('http://bbs.csdn.net/callmewhy')try: response = urlopen(req) except URLError, e: if hasattr(e, 'code'): print 'The server couldn\'t fulfill the request.' print 'Error code: ', e.code elif hasattr(e, 'reason'): print 'We failed to reach a server.' print 'Reason: ', e.reason else: print 'No exception was raised.' # everything is fine '''''' #geturl函數的應用,獲取真正的url from urllib2 import Request, urlopen, URLError, HTTPError old_url = 'http://rrurl.cn/b1UZuP' req = Request(old_url) response = urlopen(req) ? print 'Old url :' + old_url print 'Real url :' + response.geturl() '''''' #info函數的應用,獲取的頁面情況 from urllib2 import Request, urlopen, URLError, HTTPErrorold_url = 'http://www.baidu.com' req = Request(old_url) response = urlopen(req) print 'Info():' print response.info() '''''' # -*- coding: utf-8 -*- import urllib2# 創建一個密碼管理者 password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()# 添加用戶名和密碼top_level_url = "http://example.com/foo/"# 如果知道 realm, 我們可以使用他代替 ``None``. # password_mgr.add_password(None, top_level_url, username, password) password_mgr.add_password(None, top_level_url,'why', '1223')# 創建了一個新的handler handler = urllib2.HTTPBasicAuthHandler(password_mgr)# 創建 "opener" (OpenerDirector 實例) opener = urllib2.build_opener(handler)a_url = 'http://www.baidu.com/'# 使用 opener 獲取一個URL opener.open(a_url)# 安裝 opener. # 現在所有調用 urllib2.urlopen 將用我們的 opener. urllib2.install_opener(opener) '''import urllib2 enable_proxy = True proxy_handler = urllib2.ProxyHandler({"http" : 'http://some-proxy.com:8080'}) null_proxy_handler = urllib2.ProxyHandler({}) if enable_proxy:opener = urllib2.build_opener(proxy_handler) else:opener = urllib2.build_opener(null_proxy_handler) urllib2.install_opener(opener)總結
- 上一篇: ajax流式传输,如何使用AjaxFil
- 下一篇: 超级玛丽游戏开发五(动作音效)