1. 程式人生 > >Python之爬蟲-- cookie & session(二)

Python之爬蟲-- cookie & session(二)

這一片是繼 《Python之爬蟲-- cookie & session》這一篇之後在網上找到的一篇小練習,也是對cookie有更深的認識

一、為什麼要使用Cookie

    Cookie,指某些網站為了辨別使用者身份、進行session跟蹤而儲存在使用者本地終端上的資料(通常經過加密)。 
    比如說有些網站需要登入後才能訪問某個頁面,在登入之前,你想抓取某個頁面內容,登陸前與登陸後是不同的,或者不允許的。 
    使用Cookie和使用代理IP一樣,也需要建立一個自己的opener。在HTTP包中,提供了cookiejar模組,用於提供對Cookie的支援。

 

 http.cookiejar功能強大,我們可以利用本模組的CookieJar類的物件來捕獲cookie並在後續連線請求時重新發送,比如可以實現模擬登入功能。該模組主要的物件有CookieJar、FileCookieJar、MozillaCookieJar、LWPCookieJar。

    它們的關係: CookieJar–派生–>FileCookieJar–派生–>MozillaCookieJar和LWPCookieJar

    工作原理:建立一個帶有cookie的opener,在訪問登入的URL時,將登入後的cookie儲存下來,然後利用這個cookie來訪問其他網址。檢視登入之後才能看到的資訊。

    同樣,我們以例項進行講解,爬取伯樂線上的面向物件的漂亮MM的郵箱聯絡方式。

二、實戰

1.背景介紹

    在伯樂線上有這麼一個有趣的模組,面向物件,它說白了就是提供了一個程式設計師(媛)網上相親的平臺。

    URL:http://date.jobbole.com/

    它的樣子是這樣的:

 

    可以看到,這裡有很多的相親貼,隨便點進去就會有網上相親MM的詳細資訊,想獲取MM的聯絡方式,需要積分,積分可以通過簽到的方式獲取。如果沒有登陸賬戶,獲取聯絡方式的地方是這個樣子的:

 如果登陸了賬號,獲取聯絡方式的地方是這個樣子的:

想要爬取MM的聯絡郵箱,就需要用到我們本次講到的知識,Cookie的使用。當然,首先你積分也得夠。在講解之前,推薦一款抓包工具–Fiddler,可以在Google Chrome的Google商店下載這個外掛,它的樣子是這樣的:

可以看到,通過這個外掛,我們可以很容易找到Post的Form Data等資訊,很方便,當然也可以用之前講得瀏覽器審查元素的方式檢視這些資訊。

2.過程分析

    在伯樂線上首頁點選登陸的按鈕,Fiddler的抓包內容如下:

 

 Form Data的內容記住,這些是我們程式設計需要用到的。user_login是使用者名稱,user_pass是使用者密碼。

    在點選取得聯絡郵箱按鈕的時候,Fiddler的抓包內容如下:

 

    從上圖可以看出,此刻真正請求的url是

http://www.jobbole.com/wp-admin/admin-ajax.php

同樣Form Data中內容要記下來。postId是每個帖子的id。例如,開啟一個相親貼,它的URL是http://date.jobbole.com/4128/,那麼它的這個postId就是4128。為了簡化程式,這裡就不講解如何自動獲取這個postId了,本例項直接指定postId。如果想要自動獲取,可以使用beautifulsoup解析http://date.jobbole.com/返回的資訊。beautifulsoup的使用。有機會的話,會在後面的爬蟲筆記中進行講解。

3.測試

    1)將Cookie儲存到變數中

    首先,我們先利用CookieJar物件實現獲取cookie的功能,儲存到變數中,先來感受一下:

# -*- coding: UTF-8 -*-
from urllib import request
from http import cookiejar

if __name__ == '__main__':
    #宣告一個CookieJar物件例項來儲存cookie
    cookie = cookiejar.CookieJar()
    #利用urllib.request庫的HTTPCookieProcessor物件來建立cookie處理器,也就CookieHandler
    handler=request.HTTPCookieProcessor(cookie)
    #通過CookieHandler建立opener
    opener = request.build_opener(handler)
    #此處的open方法開啟網頁
    response = opener.open('http://www.baidu.com')
    #列印cookie資訊
    for item in cookie:
        print('Name = %s' % item.name)
        print('Value = %s' % item.value)

    我們使用以上方法將cookie儲存到變數中,然後打印出了cookie中的值,執行結果如下:

 

2)儲存Cookie到檔案

    在上面的方法中,我們將cookie儲存到了cookie這個變數中,如果我們想將cookie儲存到檔案中該怎麼做呢?方便以後直接讀取檔案使用,這時,我們就要用到FileCookieJar這個物件了,在這裡我們使用它的子類MozillaCookieJar來實現Cookie的儲存,編寫程式碼如下:

# -*- coding: UTF-8 -*-
from urllib import request
from http import cookiejar

if __name__ == '__main__':

    #設定儲存cookie的檔案,同級目錄下的cookie.txt
    filename = 'cookie.txt'
    #宣告一個MozillaCookieJar物件例項來儲存cookie,之後寫入檔案
    cookie = cookiejar.MozillaCookieJar(filename)
    #利用urllib.request庫的HTTPCookieProcessor物件來建立cookie處理器,也就CookieHandler
    handler=request.HTTPCookieProcessor(cookie)
    #通過CookieHandler建立opener
    opener = request.build_opener(handler)
    #此處的open方法開啟網頁
    response = opener.open('http://www.baidu.com')
    #儲存cookie到檔案
    cookie.save(ignore_discard=True, ignore_expires=True)

cookie.save的引數說明:

  • ignore_discard的意思是即使cookies將被丟棄也將它儲存下來;

  • ignore_expires的意思是如果在該檔案中cookies已經存在,則覆蓋原檔案寫入。

    在這裡,我們將這兩個全部設定為True。

    執行之後,cookies將被儲存到cookie.txt檔案中。我們可以檢視自己檢視下cookie.txt這個檔案的內容。

    3)從檔案中獲取Cookie並訪問

    我們已經做到把Cookie儲存到檔案中了,如果以後想使用,可以利用下面的方法來讀取cookie並訪問網站,感受一下:

# -*- coding: UTF-8 -*-
from urllib import request
from http import cookiejar

if __name__ == '__main__':
    #設定儲存cookie的檔案的檔名,相對路徑,也就是同級目錄下
    filename = 'cookie.txt'
    #建立MozillaCookieJar例項物件
    cookie = cookiejar.MozillaCookieJar()
    #從檔案中讀取cookie內容到變數
    cookie.load(filename, ignore_discard=True, ignore_expires=True)
    #利用urllib.request庫的HTTPCookieProcessor物件來建立cookie處理器,也就CookieHandler
    handler=request.HTTPCookieProcessor(cookie)
    #通過CookieHandler建立opener
    opener = request.build_opener(handler)
    #此用opener的open方法開啟網頁
    response = opener.open('http://www.baidu.com')
    #列印資訊
    print(response.read().decode('utf-8'))

瞭解到以上內容,我們那就可以開始正式編寫模擬登陸伯樂線上的程式了。同時,我們也可以獲取相親MM的聯絡方式。

4.編寫程式碼

    我們利用CookieJar物件實現獲取cookie的功能,儲存到變數中。然後使用這個cookie變數建立opener,使用這個設定好cookie的opener即可模擬登陸,同筆記四中講到的IP代理的使用方法類似。

    建立cookie_test.py檔案,編寫程式碼如下:

# -*- coding: UTF-8 -*-
from urllib import request
from urllib import error
from urllib import parse
from http import cookiejar

if __name__ == '__main__':
    #登陸地址
    login_url = 'http://www.jobbole.com/wp-admin/admin-ajax.php'    
    #User-Agent資訊                   
    user_agent = r'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36'
    #Headers資訊
    head = {'User-Agnet': user_agent, 'Connection': 'keep-alive'}
    #登陸Form_Data資訊
    Login_Data = {}
    Login_Data['action'] = 'user_login'
    Login_Data['redirect_url'] = 'http://www.jobbole.com/'
    Login_Data['remember_me'] = '0'         #是否一個月內自動登陸
    Login_Data['user_login'] = '********'       #改成你自己的使用者名稱
    Login_Data['user_pass'] = '********'        #改成你自己的密碼
    #使用urlencode方法轉換標準格式
    logingpostdata = parse.urlencode(Login_Data).encode('utf-8')
    #宣告一個CookieJar物件例項來儲存cookie
    cookie = cookiejar.CookieJar()
    #利用urllib.request庫的HTTPCookieProcessor物件來建立cookie處理器,也就CookieHandler
    cookie_support = request.HTTPCookieProcessor(cookie)
    #通過CookieHandler建立opener
    opener = request.build_opener(cookie_support)
    #建立Request物件
    req1 = request.Request(url=login_url, data=logingpostdata, headers=head)

    #面向物件地址
    date_url = 'http://date.jobbole.com/wp-admin/admin-ajax.php'
    #面向物件
    Date_Data = {}
    Date_Data['action'] = 'get_date_contact'
    Date_Data['postId'] = '4128'
    #使用urlencode方法轉換標準格式
    datepostdata = parse.urlencode(Date_Data).encode('utf-8')
    req2 = request.Request(url=date_url, data=datepostdata, headers=head)
    try:
        #使用自己建立的opener的open方法
        response1 = opener.open(req1)
        response2 = opener.open(req2)
        html = response2.read().decode('utf-8')
        index = html.find('jb_contact_email')
        #列印查詢結果
        print('聯絡郵箱:%s' % html[index+19:-2])

    except error.URLError as e:
        if hasattr(e, 'code'):
            print("HTTPError:%d" % e.code)
        elif hasattr(e, 'reason'):
            print("URLError:%s" % e.reason)

5.執行結果如下: