首先,推薦兩個關於python爬蟲不錯的博客:Python爬蟲入門教程專欄 和 Python爬蟲學習系列教程 。寫的都很是不錯,我學習到了不少東西!在此,我就我看到的學到的進行總結一下!javascript
爬蟲就是一個不斷的去抓去網頁的程序,根據咱們的須要獲得咱們想要的結果!但咱們又要讓服務器感受是咱們人在經過瀏覽器瀏覽不是程序所爲!歸根到底就是咱們經過程序訪問網站獲得html代碼,而後分析html代碼獲取有效內容的過程。下面讓咱們從最簡單的爬蟲開始:html
爬取一個頁面源代碼java
在python中,抓取網頁的庫是urllib2。下面看一個最簡單的例子:python
1 import urllib2 2 response = urllib2.urlopen('http://www.baidu.com/') 3 html = response.read() 4 print html
執行完成後你會發現窗口中打出了一堆代碼,其實就是百度主頁的html代碼!(抵制百度!!!)瀏覽器
咱們來看一下urlopen的用法:安全
1 >>> help(urllib2.urlopen) 2 Help on function urlopen in module urllib2: 3 4 urlopen(url, data=None, timeout=<object object>, cafile=None, capath=None, cadefault=False, context=None)
第一個參數爲url,第二個爲要發送的數據,第三個是超時時間。其他的咱們通常不用,就不解釋了!第二三個參數不是必須的,由於都有默認值,data默認值爲None,timeout默認值爲socket._GLOBAL_DEFAUTL_TIMEOUT。傳入url以後,咱們獲得一個response對象,返回的信息就在這裏面!經過response.read()獲取裏面的內容。一樣的咱們能夠構造一個Request類,做爲參數傳入urlopen中,這個Request類中就包含url,data,timeout等內容。上面的代碼咱們能夠寫成這樣:服務器
1 import urllib2 2 3 request = urllib2.Request("http://www.baidu.com") 4 response = urllib2.urlopen(request) 5 print response.read()
這樣是否是很清晰明瞭了?在構建Request的時候咱們一般會加入不少內容,咱們發出一個請求,服務器給咱們一個響應。一個簡單的爬蟲就這樣起飛了!cookie
POST和GET數據傳送app
日常咱們在瀏覽網頁的時候不免涉及到登陸註冊,填寫表單,或者跳轉到某個頁面,這時候咱們要跟服務器進行交互,向服務器發送數據,發送數據的方式呢就是Post和Get,二者的區別在於GET方式直接以連接的形式訪問,連接中包含全部的參數,如:http://www.baidu.com/shit?result=true 其中 result=true就是Get傳遞的數據,POST至關於Get就安全多了,它不會在連接上顯示全部參數。python爬蟲
Post方式:
1 import urllib 2 import urllib2 3 4 values = {} 5 values['username'] = "977610289@qq.com" 6 values['password'] = "******" 7 data = urllib.urlencode(values) 8 url = "http://www.xxx.com/login?from=http://xxx/loginInfo" 9 request = urllib2.Request(url,data) 10 response = urllib2.urlopen(request) 11 print response.read()
在上面的代碼中,咱們建立了一個字典values,設置了username和password的值,而後經過urlencode函數將字典進行轉碼,命名爲data,而後用url和data實例化了一個Request類,傳遞給urlopen()。
Get方式:
1 import urllib 2 import urllib2 3 4 values={} 5 values['username'] = "977610289@qq.com" 6 values['password']="******" 7 data = urllib.urlencode(values) 8 url = "http://www.xxx.com/login" 9 geturl = url + "?"+data 10 request = urllib2.Request(geturl) 11 response = urllib2.urlopen(request) 12 print response.read()
在上面的代碼中,咱們建立了一個字典values,設置了username和password的值,而後經過urlencode函數將字典進行轉碼,命名爲data,而後咱們把data拼接在了url中,咱們會獲得這樣的url:http://www.xxx.com/login?username=977610289%40qq.com&password=******。
在實現一個爬蟲的時候,咱們要根據須要,選擇post或者get方式進行訪問!不過除了上面那些還不夠,如今網站爲了不爬蟲去訪問會進行一些檢測,若是檢測不經過就不會響應你的請求,爲了徹底模擬瀏覽器工做,咱們每每要設置一些headers屬性,以及防盜鏈:
1 headers = { 'User-Agent' : 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' , 2 'Referer':'http://www.zhihu.com/articles' }
3 request = urllib2.Request(url, data, headers)#利用data headers構造Request對象
有些網站可能會檢測ip等,咱們可能會用到urllib2的代理,有些網站響應過慢咱們能夠設置其timeout。在訪問網站的狀況下咱們可能會遇到一些網站錯誤,咱們要在程序中進行處理(一如既往的try... except...獲得錯誤信息內容):
1 import urllib2 2 3 req = urllib2.Request('http://www.xxx.com') 4 try: 5 urllib2.urlopen(req) 6 except urllib2.URLError, e: 7 if hasattr(e,"code"): 8 print e.code 9 if hasattr(e,"reason"): 10 print e.reason 11 else: 12 print "OK"
常見的錯誤代碼:400 非法請求 403 禁止訪問 404 未找到資源 500 服務器內部錯誤 200 訪問成功。
在網頁訪問過程當中,不可避免的要用到cookies,咱們的程序要模擬瀏覽器的行爲,在訪問網頁的時候有時候要帶上特定的cookies,這樣才能成功訪問網頁。關於cookies咱們用到了cookielib,cookielib模塊提供可存儲cookie的對象,以便於與urllib2配合使用進行網站訪問,利用其中的CookieJar類捕獲和發送cookie,實現模擬登陸,維持登陸狀態等。
獲取cookie保存到變量:
1 import urllib2 2 import cookielib 3 #聲明一個CookieJar對象實例來保存cookie 4 cookie = cookielib.CookieJar() 5 #利用urllib2庫的HTTPCookieProcessor對象來建立cookie處理器 6 handler=urllib2.HTTPCookieProcessor(cookie) 7 #經過handler來構建opener 8 opener = urllib2.build_opener(handler) 9 #此處的open方法同urllib2的urlopen方法,也能夠傳入request 10 response = opener.open('http://www.baidu.com') 11 for item in cookie: 12 print 'Name = '+item.name 13 print 'Value = '+item.value 14 #利用cookie請求訪問另外一個網址 15 gradeUrl = 'http://www.baidu.com/xxx/xx' 16 #請求訪問 17 result = opener.open(gradeUrl) 18 print result.read()
上面程序建立了一個帶有cookie的opener,在訪問登陸url的時候,將登陸後的cookie保存下來,而後利用這個cookie來訪問其餘的網址。
下面放一個HttpClient.py,裏面包含了post和get方法,以及getcookies:
1 import cookielib, urllib, urllib2, socket 2 3 class HttpClient: 4 __cookie = cookielib.CookieJar() 5 __req = urllib2.build_opener(urllib2.HTTPCookieProcessor(__cookie)) 6 __req.addheaders = [ 7 ('Accept', 'application/javascript, */*;q=0.8'), 8 ('User-Agent', 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)') 9 ] 10 urllib2.install_opener(__req) 11 12 def Get(self, url, refer=None): 13 try: 14 req = urllib2.Request(url) 15 if not (refer is None): 16 req.add_header('Referer', refer) 17 return urllib2.urlopen(req, timeout=120).read() 18 except urllib2.HTTPError, e: 19 return e.read() 20 except socket.timeout, e: 21 return '' 22 except socket.error, e: 23 return '' 24 25 def Post(self, url, data, refer=None): 26 try: 27 req = urllib2.Request(url, urllib.urlencode(data)) 28 if not (refer is None): 29 req.add_header('Referer', refer) 30 return urllib2.urlopen(req, timeout=120).read() 31 except urllib2.HTTPError, e: 32 return e.read() 33 except socket.timeout, e: 34 return '' 35 except socket.error, e: 36 return '' 37 38 def Download(self, url, file): 39 output = open(file, 'wb') 40 output.write(urllib2.urlopen(url).read()) 41 output.close() 42 43 def getCookie(self, key): 44 for c in self.__cookie: 45 if c.name == key: 46 return c.value 47 return '' 48 49 def setCookie(self, key, val, domain): 50 ck = cookielib.Cookie(version=0, name=key, value=val, port=None, port_specified=False, domain=domain, domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False) 51 self.__cookie.set_cookie(ck)