利用scrapy模擬登陸知乎

閒來無事,寫一個模擬登陸知乎的小demo。json

分析網頁發現:登陸須要的手機號,密碼,_xsrf參數,驗證碼dom

實現思路:scrapy

一、獲取驗證碼ide

二、獲取_xsrf 參數url

三、攜帶參數,請求登陸spa

驗證碼url : "https://www.zhihu.com/captcha.gif?r={t}&type=login&lang=en".format(t=t)  # t 爲時間戳code

登陸界面url : "https://www.zhihu.com/#signin"orm

手機登陸申請url : 'https://www.zhihu.com/login/phone_num'blog

實現代碼:utf-8

  首先配置文件 settings 中 ROBOTSTXT_OBEY = False  

  一、開頭及驗證碼處理部分,先重寫scrapy的start_requests方法。其次利用Pillow 來處理驗證碼,將驗證碼顯示出來,手動填寫(畢竟打碼是須要費用的),知乎默認的驗證碼爲中文,經分析發現驗證碼url 後面的 lang 參數決定語言,因此試着將語言改成英文(en)

# -*- coding: utf-8 -*-
import scrapy
import time
import json
from PIL import Image


class ZhihuSpider(scrapy.Spider):
    name = 'zhihu'
    allowed_domains = ['www.zhihu.com']

    # 重寫start_requests方法,處理驗證碼問題
    def start_requests(self):
        t = str(time.time()).replace('','.')
        # 驗證碼url
        start_urls = "https://www.zhihu.com/captcha.gif?r={t}&type=login&lang=en".format(t=t)
        self.header ={
            "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36",
            'Referer':' https: // www.zhihu.com /'
        }
        # 請求驗證碼的url
        return [scrapy.Request(url=start_urls,headers=self.header,callback=self.capcha,dont_filter=True)]

    # 獲取驗證碼
    def capcha(self,response):
        # 獲取驗證碼,將驗證馬寫入本地
        with open('capcha.jpg','wb') as f:
            f.write(response.body)
        try:
            # 利用pillow打開驗證碼
            im = Image.open('capcha.jpg')
            im.show()
        except:
            print('請打開文件%s自行輸入'%("capcha.jpg"))
        cap = input("請輸入驗證碼>>")
        data = {
            "cap":cap
        }
        log_url = "https://www.zhihu.com/#signin"
        return scrapy.Request(url=log_url,callback=self.parse_login,headers=self.header,meta=data,dont_filter=True)

  二、獲得驗證碼後,開始搞_xsrf參數,從登陸源碼中分析獲得_xsrf 在屬性爲name="_xsrf" 的input 節點中的value值

  # 解析申請登錄的頁面,獲取參數xsrf
    def parse_login(self,response):
        xsrf = response.xpath('//input[@name="_xsrf"]/@value').extract_first()
        if not xsrf:
            print("請求錯誤")
            return ''
        phone_num = input("請輸入手機號碼")
        password = input("請輸入密碼")
        data = {
            'captcha':response.meta['cap'],
            '_xsrf':xsrf,
            'password':password,
            'captcha_type':' en',
            'phone_num':phone_num
        }
        # 用手機號-密碼 登陸的url
        url = 'https://www.zhihu.com/login/phone_num'
        return scrapy.FormRequest(url=url,callback=self.login_zh,headers=self.header,formdata=data,dont_filter=True,meta={'direct_list': [301, 302], 'direct_ignore': True})

三、參數都獲取到後就能夠模擬登陸了

    # 驗證是否登陸成功
    def login_zh(self,response):
        print(json.loads(response.text)['msg'])
        url = "https://www.zhihu.com/#signin"
        # 請求登陸知乎
        yield scrapy.Request(url=url,callback=self.zh,headers=self.header,dont_filter=True,meta={'direct_list':[301,302],'direct_ignore':True})

    # 後續解析知乎登陸後的頁面
    def zh(self,response):
        print(response.text)

本次登陸後,並未對頁面進行解析,只是打印一下頁面,做爲驗證。

相關文章
相關標籤/搜索