05. URLError與Cookie
Cookie,指某些網(wǎng)站為了辨別用戶身份、進行session跟蹤而儲存在用戶本地終端上的數(shù)據(jù)(通常經(jīng)過加密)
比如說有些網(wǎng)站需要登錄后才能訪問某個頁面,在登錄之前,你想抓取某個頁面內(nèi)容是不允許的。那么我們可以利用Urllib庫保存我們登錄的Cookie,然后再抓取其他頁面就達到目的了。
1.1 Opener
當你獲取一個URL你使用一個opener(一個urllib.OpenerDirector的實例)。在前面,我們都是使用的默認的opener,也就是urlopen。它是一個特殊的opener,可以理解成opener的一個特殊實例,傳入的參數(shù)僅僅是url,data,timeout。
如果我們需要用到Cookie,只用這個opener是不能達到目的的,所以我們需要創(chuàng)建更一般的opener來實現(xiàn)對Cookie的設(shè)置
1.2 Cookielib
cookielib模塊的主要作用是提供可存儲cookie的對象,以便于與urllib模塊配合使用來訪問Internet資源。Cookielib模塊非常強大,我們可以利用本模塊的CookieJar類的對象來捕獲cookie并在后續(xù)連接請求時重新發(fā)送,比如可以實現(xiàn)模擬登錄功能。該模塊主要的對象有CookieJar、FileCookieJar、MozillaCookieJar、LWPCookieJar
案例1:獲取Cookie保存到變量
from urllib.request import HTTPCookieProcessor
from urllib.request import build_opener
from urllib.request import Request
from http.cookiejar import CookieJar
from urllib.parse import urlencode
#聲明一個CookieJar對象實例來保存cookie
cookie = CookieJar()
#利用HTTPCookieProcessor對象來創(chuàng)建cookie處理器
cookiePro = HTTPCookieProcessor(cookie)
#通過handler來構(gòu)建opener
opener = build_opener(cookiePro)
login_url = "http://www.sxt.cn/index/login/login"
header = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36"}
fromdata = {
? ?"user": "17703181473",
? ?"password": "123456"
}
data = urlencode(fromdata).encode()
request = Request(login_url, headers=header, data=data)
response = opener.open(request)
info_url = 'http://www.sxt.cn/index/user.html'
request_info = Request(info_url)
response = opener.open(request_info)
html = response.read()
print(html.decode())
我們使用以上方法將cookie保存到變量中,然后打印出了cookie中的值,運行結(jié)果如下
以上程序的原理如下
創(chuàng)建一個帶有cookie的opener,在訪問登錄的URL時,將登錄后的cookie保存下來,然后利用這個cookie來訪問其他網(wǎng)址。
案例2:cookie保存文件的讀取
from urllib.request import build_opener, Request
from urllib.request import HTTPCookieProcessor
from http.cookiejar import MozillaCookieJar
from urllib.parse import urlencode
def get_cookie():
? ?# 請求頭
? ?headers = {
? ? ? ?"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"}
? ?login_url = "http://www.sxt.cn/index/login/login.html"
? ?form_data = {
? ? ? ?"user": "17703181473",
? ? ? ?"password": "123456"
? ?}
? ?# 轉(zhuǎn)換編碼
? ?f_data = urlencode(form_data)
? ?req = Request(login_url, headers=headers, data=f_data.encode())
? ?# 創(chuàng)建保存可以序列化cookie的文件對象
? ?cookie = MozillaCookieJar("cookie.txt")
? ?# 構(gòu)造可保存cookie的控制器
? ?c_handler = HTTPCookieProcessor(cookie)
? ?# 構(gòu)造opener
? ?opener = build_opener(c_handler)
? ?# 發(fā)送請求 -- 登錄成功 (用戶名和密碼 正確)
? ?opener.open(req)
? ?cookie.save(ignore_discard=True, ignore_expires=True)
def use_cookie():
? ?# 請求頭
? ?headers = {
? ? ? ?"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"}
? ?info_url = "http://www.sxt.cn/index/user.html"
? ?# 創(chuàng)建保存可以序列化cookie的文件對象
? ?cookie = MozillaCookieJar()
? ?# 加載cookie文件
? ?cookie.load("cookie.txt", ignore_discard=True, ignore_expires=True)
? ?# 構(gòu)造可保存cookie的控制器
? ?c_handler = HTTPCookieProcessor(cookie)
? ?# 構(gòu)造opener
? ?opener = build_opener(c_handler)
? ?# 構(gòu)造訪問個人頁面請求
? ?req1 = Request(info_url, headers=headers)
? ?# 發(fā)送請求
? ?resp2 = opener.open(req1)
? ?# 打印信息
? ?print(resp2.read().decode())
if __name__ == '__main__':
? ?# get_cookie()
? ?use_cookie()
2. URLError
首先解釋下URLError可能產(chǎn)生的原因:
網(wǎng)絡(luò)無連接,即本機無法上網(wǎng)
連接不到特定的服務(wù)器
服務(wù)器不存在
在代碼中,我們需要用try-except語句來包圍并捕獲相應的異常,代碼如下:
from urllib.request import Request, urlopen
from urllib.error import URLError
url = "http://www.sx435334t.cn/index/us3er.html"
try:
? ?headers = {
? ? ? ?"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"
? ?}
? ?req = Request(url, headers=headers)
? ?resp = urlopen(url, timeout=1)
? ?print(resp.read().decode())
except URLError as e:
? ?if len(e.args) == 0:
? ? ? ?print(e.code)
? ?else:
? ? ? ?print(e.args[0])
print("獲取數(shù)據(jù)完畢")
我們利用了 urlopen方法訪問了一個不存在的網(wǎng)址,運行結(jié)果如下:
[Errno 11004] getaddrinfo failed