瀏覽器訪問WEB服務器的過程
在用戶訪問網頁時,不論是通過URL輸入域名或IP,還是點擊鏈接,瀏覽器向WEB服務器發出了一個HTTP請求(Http Request),WEB服務器接收到客戶端瀏覽器的請求之后,響應客戶端的請求,發回相應的響應信息(Http Response),瀏覽器解析引擎,排版引擎分析返回的內容,呈現給用戶。WEB應用程序在於服務器交互的過程中,HTTP請求和響應時發送的都是一個消息結構
什么是cookie
cookie在http請求和http響應的頭信息中,cookie是消息頭的一種很重要的屬性. 當用戶通過瀏覽器首次訪問一個域名時,訪問的WEB服務器會給客戶端發送數據,以保持WEB服務器與客戶端之間的狀態保持,這些數據就是Cookie,它是 Internet 站點創建的 ,為了辨別用戶身份而儲存在用戶本地終端上的數據,Cookie中的信息一般都是經過加密的,Cookie存在緩存中或者硬盤中,在硬盤中的是一些小文本文件,當你訪問該網站時,就會讀取對應網站的Cookie信息,Cookie有效地提升了我們的上網體驗。一般而言,一旦將 Cookie 保存在計算機上,則只有創建該 Cookie 的網站才能讀取它。
為什么需要cookie
Http協議是一個無狀態的面向連接的協議,Http協議是基於tcp/ip協議層之上的協議,當客戶端與服務器建立連接之后,它們之間的TCP連接一直都是保持的,至於保持的時間是多久,是通過服務器端來設置的,當客戶端再一次訪問該服務器時,會繼續使用上一次建立的連接,但是,由於Http協議是無狀態的,WEB服務器並不知道這兩個請求是否同一個客戶端,這兩次請求之間是獨立的。 為了解決這個問題, Web程序引入了Cookie機制來維護狀態.cookie可以記錄用戶的登錄狀態,通常web服務器會在用戶登錄成功后下發一個簽名來標記session的有效性,這樣免去了用戶多次認證和登錄網站。記錄用戶的訪問狀態。
比如說有些網站需要登錄后才能訪問某個頁面,在登錄之前,你想抓取某個頁面內容是不允許的,那么我們可以利用Urllib2庫保存我們登錄的Cookie,然后再抓取其他頁面就達到目的了。
cookie的種類
會話Cookie(Session Cookie):這個類型的cookie只在會話期間內有效,保存在瀏覽器的緩存之中,用戶訪問網站時,會話Cookie被創建,當關閉瀏覽器的時候,它會被瀏覽器刪除。 持久Cookie(Persistent Cookie): 這個類型的cookie長期在用戶會話中生效。當你設置cookie的屬性Max-Age為1個月的話,那么在這個月里每個相關URL的http請求中都會帶有這個cookie。所以它可以記錄很多用戶初始化或自定義化的信息,比如什么時候第一次登錄及弱登錄態等。 Secure cookie:安全cookie是在https訪問下的cookie形態,以確保cookie在從客戶端傳遞到Server的過程中始終加密的。 HttpOnly Cookie :這個類型的cookie只能在http(https)請求上傳遞,對客戶端腳本語言無效,從而有效避免了跨站攻擊。 第三方cookie: 第一方cookie是當前訪問的域名或子域名下的生成的Cookie。 第三方cookie:第三方cookie是第三方域名創建的Cookie。
cookie的構成
Cookie是http消息頭中的一種屬性,包括:Cookie名字(Name)Cookie的值(Value),Cookie的過期時間(Expires / Max-Age),Cookie作用路徑(Path),Cookie所在域名(Domain),使用Cookie進行安全連接(Secure)。 前兩個參數是Cookie應用的必要條件,另外,還包括Cookie大小(Size,不同瀏覽器對Cookie個數及大小限制是有差異的)。
urllib與urllib2庫的區別
1、為什么它們總是成對出現
urllib與urllib2都做與url請求相關的操作,但它們提供不同的功能.
urllib2.urlopen()可以接受一個Request對象或一個url(可以在request對象中設置data,headers等),以實現高級的url請求,但無urlencode功能。 urllib.urlopen()只能接受一個url,所以只能實現簡單的url請求,但urllib有urlencode功能。
urllib.urlencode功能是什么呢?它可以把字典變成url需要的字符串!
#!/usr/bin/env python # -*- coding:utf-8 -*- # __author__:kzg # 要獲取數據的url及referer tUrl = 'http://product.weather.com.cn/alarm/webdata/1012305-20170820132000-0902.html' reFer = 'http://www.weather.com.cn/alarm/newalarmcontent.shtml?file=1012305-20170820132000-0902.html' import urllib2 import urllib # 定義一個request實例 r = urllib2.Request(url=tUrl) # 給request添加頭信息 r.add_header('Referer',reFer) r.add_header('User-Agent':'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36') # 給request添加post數據(此時的請求為post,而不再是get) r.add_data(urllib.urlencode({'name':'kong','age':15})) # 打印reauest實例中的header和data print(r.headers) print(r.data) 結果: {'Referer': 'http://www.weather.com.cn/alarm/newalarmcontent.shtml?file=1012305-20170820132000-0902.html', 'User-agent': 'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36'} age=15&name=kong
2、opener
urllib2.urlopen: 是opener的一個特殊實例,也是默認的opener,傳入的參數較少,僅僅有url,data,timeout,headers等。
通過閱讀源碼我們知道,urllib2.urlopen(url)其實也是調用opener.open(url)來請求url,但是默認的opener並不支持cookie.我們可以使用HTTPCookieProcessor來創建一個支持cookie的opener,它需要傳入一個cookie容器。
3、cookielib
cookielib模塊的主要作用是:提供一個對象來存儲cookie,然后帶入urllib2中去訪問網站。我們可以利用它的cookiejar類的對象來捕獲cookie,並在后續連接請求時自動重新發送,來實現模擬登陸功能。
該模塊主要的對象有CookieJar、FileCookieJar、MozillaCookieJar、LWPCookieJar。
它們的關系:CookieJar —-派生—->FileCookieJar —-派生—–>MozillaCookieJar和LWPCookieJar
實例講解
1、自動獲取cookie(CookieJar)
#!/usr/bin/env python # _*_ coding:utf-8 _*_ import urllib import urllib2 import cookielib loginUrl='http://www.renren.com/PLogin.do' # 創建cookie容器 cj = cookielib.CookieJar() # 創建支持cookie的opener handler = urllib2.HTTPCookieProcessor(cj) opener = urllib2.build_opener(handler)
urllib2.install_opener(opener) # 使用此opener來請求url response = opener.open(loginUrl) # 查看獲取到的cookie for each in cj: print each.name,each.value
2、在自動獲取cookie的同時寫入到文件中(MozillaCookieJar)
#!/usr/bin/env python # _*_ coding:utf-8 _*_ import urllib import urllib2 import cookielib loginUrl='http://www.renren.com/PLogin.do' # 創建cookie容器 cj = cookielib.MozillaCookieJar('cookie.txt') # 創建支持cookie的opener handler = urllib2.HTTPCookieProcessor(cj) opener = urllib2.build_opener(handler) # 使用此opener請求url response = opener.open(loginUrl) #查看獲取到的cookie for each in cj: print each.name,each.value
#保存 cj.save(ignore_expires=True,ignore_discard=True)
此例與上例的不同之處在於使用了MozillaCookieJar,它既有自動獲取cookie的功能,又具有與文件的交互。
關於最后save方法的兩個參數在此說明一下:
官方解釋如下:
ignore_discard: save even cookies set to be discarded.
ignore_expires: save even cookies that have expired.The file is overwritten if it already exists
3、從文件中加載cookie
#!/usr/bin/env python # _*_ coding:utf-8 _*_ import urllib import urllib2 import cookielib loginUrl='http://www.renren.com/PLogin.do' # 創建cookie容器 cj = cookielib.MozillaCookieJar() cj.load('cookie.txt',ignore_discard=True,ignore_expires=True) # 創建支持cookie的opener handler = urllib2.HTTPCookieProcessor(cj) opener = urllib2.build_opener(handler) # 使用此opener來請求url response = opener.open(loginUrl)
4、模擬登陸網站(以人人網為例)
准備:要登陸人人網需要哪些信息呢?
1、登陸地址url
2、登陸用戶名屬性
3、登陸密碼屬性
如圖所示:
要實現的事情:
使用cookie自動登陸網站,並獲取我的主頁資料信息。
首先來個截圖,預先看看我的主頁資料信息的HTML結構吧。
示例代碼:
#!/usr/bin/env python # _*_ coding:utf-8 _*_ import urllib import urllib2 import cookielib class renren_login(object): def __init__(self): self.name = '' self.pwd = '' # 設置存儲cookie的容器 self.cj = cookielib.CookieJar() # 使opener支持cookie self.handler = urllib2.HTTPCookieProcessor(self.cj) # 創建一個支持cookie的opener self.opener = urllib2.build_opener(self.handler) urllib2.install_opener(self.opener) def set_user_pwd(self,username,password): self.name = username self.pwd = password def login(self,url): # 將字典對象編碼帶到url中 post_data = urllib.urlencode({'email':self.name,'password':self.pwd}) # 簡單的反爬 head = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36'} # 將提交信息封裝成request對象 req = urllib2.Request(url,data=post_data,headers=head) # 對request對象發出請求 response = self.opener.open(req) # 判斷url是否跳轉 if response.url != url: return True else: return False exit(1) def get_response(self,url): # 讀取請求到的內容 response = self.opener.open(url).read() return response if __name__ == '__main__': #設置網站的登陸信息 LoginUrl = 'http://www.renren.com/PLogin.do' username = '15201417639' password = 'kongzhagen.com' #初始化類 cls = renren_login() #設置用戶名及密碼 cls.set_user_pwd(username,password) #登陸網站:返回主站的地址 http://www.renren.com/913043576,登陸成功 if cls.login(LoginUrl): # 我的主頁資料信息 url='http://follow.renren.com/list/913043576/pub/v7' ret = cls.get_response(url) print ret.decode('utf-8')
OK,完工啦,把返回的結果ret與上面的主頁資料信息的HTML比比看吧。
額,還不成功,我的用戶名和密碼都改啦,換成你自己的試試!!