本節內容
在訪問網站的時候,我們經常遇到有些頁面必須用戶登錄才能訪問。這個時候我們之前寫的傻傻的爬蟲就被ban在門外了。所以本節,我們給爬蟲配置cookie,使得爬蟲能保持用戶已登錄的狀態,達到獲得那些需登錄才能訪問的頁面的目的。
由於本節只是單純的想保持一下登陸狀態,所以就不寫復雜的獲取頁面了,還是像本教程的第一部分一樣,下載個網站主頁驗證一下就ok了。本節github戳此處。
原理
一般情況下,網站通過存放在客戶端的一個被稱作cookie的小文件來存放用戶的登陸信息。在瀏覽器訪問網站的時候,會把這個小文件發往服務器,然后服務器根據這個小文件確定你的身份,然后返回給你特定的信息。
我們要做的就是盡量模擬瀏覽器的行為,在使用爬蟲訪問網站時也帶上cookie來訪問。
前提
前提當然是你有個賬號了,目前本教程一直使用的論壇心韻論壇是我本人搭建的,已經被各種爬蟲發的廣告水的不要不要的了,為了本教程,仍然是開放注冊並一直開着服。但不保證會一直開着,不過根據本教程的講解,爬取別的Discuz框架論壇一般是沒問題的。扯遠了……
獲取cookie
按照以下步驟操作
- 登陸論壇,進入主頁
- 按F12進入Chrome或Firefox的開發者調試工具,選擇Network選項卡
- 按F5刷新一下頁面
- 選擇Doc子選項卡
- 找到主頁的請求和返回情況
- 找到Request Headers
- 復制出cookie
如圖:

把cookie轉化格式
在scrapy中,設置cookie需要是字典格式的,可是我們從瀏覽器Copy出來的是字符串格式的,所以我們需要寫個小程序來轉化一下
transCookie.py
# -*- coding: utf-8 -*- class transCookie: def __init__(self, cookie): self.cookie = cookie def stringToDict(self): ''' 將從瀏覽器上Copy來的cookie字符串轉化為Scrapy能使用的Dict :return: ''' itemDict = {} items = self.cookie.split(';') for item in items: key = item.split('=')[0].replace(' ', '') value = item.split('=')[1] itemDict[key] = value return itemDict if __name__ == "__main__": cookie = "你復制出的cookie" trans = transCookie(cookie) print trans.stringToDict()
運行的效果如圖

然后把這個字典復制出來。
給scrapy配置cookie
首先把剛才得到的cookie放到settings.py里
settings.py
# -*- coding: utf-8 -*- BOT_NAME = 'heartsong' SPIDER_MODULES = ['heartsong.spiders'] NEWSPIDER_MODULE = 'heartsong.spiders' ROBOTSTXT_OBEY = False # 不遵守Robot協議 # 使用transCookie.py翻譯出的Cookie字典 COOKIE = {'key1': 'value1', 'key2': 'value2'}
然后編寫爬蟲文件
heartsong_spider.py
# -*- coding: utf-8 -*- # import scrapy # 可以用這句代替下面三句,但不推薦 from scrapy.spiders import Spider from scrapy import Request from scrapy.conf import settings class HeartsongSpider(Spider): name = "heartsong" allowed_domains = ["heartsong.top"] # 允許爬取的域名,非此域名的網頁不會爬取 start_urls = [ # 主頁,此例只下載主頁,看是否有登錄信息 "http://www.heartsong.top/forum.php" ] cookie = settings['COOKIE'] # 帶着Cookie向網頁發請求 # 發送給服務器的http頭信息,有的網站需要偽裝出瀏覽器頭進行爬取,有的則不需要 headers = { 'Connection': 'keep - alive', # 保持鏈接狀態 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36' } # 對請求的返回進行處理的配置 meta = { 'dont_redirect': True, # 禁止網頁重定向 'handle_httpstatus_list': [301, 302] # 對哪些異常返回進行處理 } # 爬蟲的起點 def start_requests(self): # 帶着cookie向網站服務器發請求,表明我們是一個已登錄的用戶 yield Request(self.start_urls[0], callback=self.parse, cookies=self.cookie, headers=self.headers, meta=self.meta) # Request請求的默認回調函數 def parse(self, response): with open("check.html", "wb") as f: f.write(response.body) # 把下載的網頁存入文件
總的來說一句話,就是帶着cookie發起Request請求。
運行之后會將主頁保存,我們打開文件查看一下效果

小結
本節介紹了cookie的獲取方法和如何給scrapy設置cookie,下節我會介紹如果帶着登陸狀態去回復主題帖。

