從零開始學習scrapy:一,使用scrapy模擬登錄並獲取頁面數據

從零開始學習scrapy:一,使用scrapy模擬登錄並獲取頁面數據

前言

本次需要獲取數據的網址是 http://www.zimuzu.tv/today
這裏寫圖片描述
這是登錄情況下訪問顯示的界面
我們的目標是獲取所有當天更新的美劇名字

假設

我們嘗試一下在沒有登錄情況下訪問這個頁面,會是一個什麼樣的情況
這裏寫圖片描述
我們可以看到,“請登錄網站”的字樣。
這個我們可以作爲程序判斷是否需要運行模擬登錄流程的條件

過程

本過程是直接從新建了scrapy項目並在Pycharm上運行開始

第一步

定義數據實體
找到項目中的items.py文件

import scrapy

class MovieItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    name = scrapy.Field()

因爲我們這次簡單例子只是想獲取美劇的名字,所以只定義一個name就可以了

編寫爬蟲邏輯

import scrapy
from  scrapy import log
from movie.items import MovieItem

class MeijuSpider(scrapy.Spider):
    name = 'meiju'
    allowed_domains = ['zimuzu.tv']
    start_urls = ['http://www.zimuzu.tv/today']
    header = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36"}  # 供登錄模擬使用

我們新建的MeijuSpider只繼承了最普通的Spider,但是由於我們有可能需要做登錄的操作,所以我們需要重載函數start_requests

    def start_requests(self):
        return [scrapy.FormRequest(
            url='http://www.zimuzu.tv/today',
            dont_filter=True,
            meta={'cookiejar': 1},
            callback=self.parse
        )]

參數一個個來解析:

  • url:就是本次需要訪問地址

  • dont_filter:是用於重複請求的,第一次請求發現需要登錄操作,在登錄操作完成後,要再一次訪問這個url,如果不添加這個,會出現以下錯誤:

2018-06-21 00:05:35 [scrapy.dupefilters] DEBUG: Filtered duplicate request: <GET http://www.zimuzu.tv/today> - no more duplicates will be shown (see DUPEFILTER_DEBUG to show all duplicates)
2018-06-21 00:05:35 [scrapy.core.engine] INFO: Closing spider (finished)
2018-06-21 00:05:35 [scrapy.statscollectors] INFO: Dumping Scrapy stats:
  • meta={'cookiejar': 1}:這代表本次請求開啓cookie

  • callback:設置本次訪問成功後的回調函數

首次回調

    def parse(self, response):
        log.msg(response.body.decode('utf-8'))
        # 判斷有沒有登錄
        if "請登錄" in response.body.decode('utf-8'):
            log.msg("need to login")
            log.msg("start login")
            return self.login(response)
        else:
            log.msg(response.body.decode('utf-8'))
            return self.getMovieList(response)

首先我們拿到response後需要把它轉換成utf-8的格式才能進行判斷
如果有請登錄,就進入登錄流程,調用login函數

   def login(self,response):

        fd = {'account':'xxxxxxx',#你的賬號
                    'password':'*******',#你的密碼
                   'remember':'1',
                   'url_back':'http%3A%2F%2Fwww.zimuzu.tv%2F'}


        return [scrapy.FormRequest(
            url='http://www.zimuzu.tv/User/Login/ajaxLogin',
            formdata=fd,
            meta={'cookiejar': response.meta['cookiejar']},
            callback=self.afterLogin
        )]

就是做登錄的請求,至於請求需要的字段,就是在瀏覽器抓取的
這次因爲帶有登錄信息,所以就一次表單請求
formdata:請求的表單數據集
回調函數是afterLogin

    def afterLogin(self,response):
        cookie = response.headers.getlist('Set-Cookie')

        print('cookie:',cookie)
        url = 'http://www.zimuzu.tv/today'
        return [scrapy.FormRequest(
            url=url,
            dont_filter=True,
            meta={"cookiejar": True},
            callback=self.parse
        )]

這個的日誌我們可以看到打印出來的cookie信息:

cookie: [b’GINFO=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/; domain=.zimuzu.tv’, b’GKEY=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/; domain=.zimuzu.tv’, b’GINFO=uid%3D3548633%26nickname%3Dnickey0781%26group_id%3D1%26avatar_t%3Dhttp%3A%2F%2Ffiles.zmzjstu.com%2Fftp%2Favatar%2Ff_noavatar_t.gif%26main_group_id%3D0%26common_group_id%3D59; expires=Sun, 18-Jun-2028 15:40:04 GMT; Max-Age=315360000; path=/; domain=.zimuzu.tv’, b’GKEY=bb9df3e025695bfa45484ad26d7a3ac3; expires=Sun, 18-Jun-2028 15:40:04 GMT; Max-Age=315360000; path=/; domain=.zimuzu.tv; httponly’]

接下來就可以用回第一個回調函數parse ,這次因爲帶上了cookie信息,所以是可以獲得數據的,就會調用函數getMovieList

    def getMovieList(self, response):
        movies = response.xpath('//table[@class="d_r_t"][@day="06-17"]/tr')
        for m in movies:
            movieName = m.xpath('./td/a/text()').extract()
            # print('move name size:',len(movieName))
            print('move name:',movieName)
            if (len(movieName) > 0):
                item = MovieItem()
                item['name'] = movieName[0]
                yield item


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章