(八)爬蟲之js調試(登錄知乎)

  上次爬取網易雲音樂,折騰js調試了很久,難受。。。。今天繼續練練手,研究下知乎登錄,讓痛苦更猛烈些。node

1.簡單分析python

  很容易就發現登錄的url=「https://www.zhihu.com/api/v3/oauth/sign_in」,post方法提交,須要的請求頭和表單數據以下兩圖,請求頭中有一個特殊的x-xsrftoken,表單數據爲加密後的一長串字符竄,所以須要構造這兩個值便可。c++

 

 

2. 獲取 x-xsrftoken值web

   首先是這個特殊的x-xsrftoken,發現經過訪問url="https://www.zhihu.com/",返回的cookies裏面能拿到(會自動重定向,須要禁止重定向拿到requests.get(url,headers=headers,allow_redirects=False)),代碼以下:json

headers={"User-Agent":"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36",}
def get_xsrf(headers): url
="https://www.zhihu.com/" r = requests.get(url,headers=headers,allow_redirects=False) #禁止重定向時,cookies裏面有xsrf參數 xsrf = r.cookies["_xsrf"]

 

3. 構造表單數據api

  而後就是表單數據的構造和加密了, 根據前輩們的提示,提交url爲url=「https://www.zhihu.com/api/v3/oauth/sign_in」,通常表單會和末尾部分/oauth/sign_in有關係,因而在js文件裏面搜索sign_in時,發現了下面的API,經過添加斷點,點擊登陸,而後執行到斷點處時,看到了以下的表單數據。變換不一樣帳號試了下,發現只有captcha,signature,timestamp三個值在改變,其餘參數不變。很明顯,captcha爲驗證碼,timestamp爲時間戳(注意是13位),signature也像一個加密值,接下來就是尋找這幾個值構造表單了。瀏覽器

表單數據:服務器

  3.1 構造signaturecookie

    對於signature,在js文件中搜索signature,發現了下面的signature關鍵字,一樣打斷點,發現signature是採用hmac對四個數據加密後的結果;加密方  法爲sha1,salt值以下,而後加密的參數依次是e=「password」, u="c3cef7c66a1843f8b3a9e6a1e3160e20"(就是clientId), source="com.zhihu.web", n爲13爲  時間戳。用python實現代碼以下:app

def get_signature(grantType,clientId,source,timestamp):
    h = hmac.new("d1b964811afb40118a12068ff74a12f4","",hashlib.sha1)
    h.update(grantType+clientId+source+str(timestamp))
    return h.hexdigest()

  3.2 構造captcha

    而後是處理驗證碼captcha參數,發現有三種狀況:

    1. 不須要驗證碼,captcha=""

    2. 請求驗證碼的url爲"https://www.zhihu.com/api/v3/oauth/captcha?lang=cn",返回爲漢字圖片,須要點擊圖片中倒立的漢字,captcha爲座標值

               3.請求驗證碼的url爲"https://www.zhihu.com/api/v3/oauth/captcha?lang=en",返回英文字母圖片,輸入圖片中英文字符便可,captcha爲英文字符

   驗證碼的請求和處理流程以下:

    首先向上述兩個驗證碼請求url中任一個發送get請求,若是返回{show_captcha:False},不須要驗證碼,captcha="",直接返回便可;若是返回{show_captcha:True},則須要驗證碼,繼續向該url發送put請求(須要第一步的cookie),服務器會返回base64編碼的驗證碼圖片,利用base64解碼寫入文件即爲驗證碼圖片。打開圖片,根據要求輸入驗證碼或點擊圖片即爲captcha的值,這裏須要先攜帶cookie和驗證碼值,向服務器發送post請求,返回success才表示驗證成功。比較特殊的是中文驗證碼處理,驗證碼的值爲幾組座標值,以下第二張圖片所示,能夠利用matplotlib.pyplot模塊來獲取圖片點擊的座標值(注意提交結果爲實際點擊座標的一半)。

驗證碼:

 驗證碼結果返回:

驗證碼處理的代碼以下:

def get_captcha(lang,headers):
    if lang=="cn":
        api = "https://www.zhihu.com/api/v3/oauth/captcha?lang=cn"
    else:
        api = "https://www.zhihu.com/api/v3/oauth/captcha?lang=en"
        
    ret = requests.get(api,headers=headers)
    cookies = ret.cookies
    show_captcha = re.search("true",ret.text)
    captcha=""
    if show_captcha:
        img_res = requests.put(api,headers=headers,cookies=cookies)  #得帶上第一步的cookie,不然返回,{u'code': 120002, u'name': u'ERR_CAPSION_TICKET_NOT_FOUND'}
        img_json = json.loads(img_res.text)
        img_data = img_json["img_base64"].replace("\n","")
        with open("captcha.jpg","wb") as i:
            i.write(base64.b64decode(img_data))
        img = Image.open("captcha.jpg")
        if lang=="cn":
            plt.imshow(img)
            print("點擊圖片中全部倒立的漢字,在命令行中按回車鍵提交")
            points = plt.ginput(7) #阻塞點擊七次後返回(或者中途點擊回車鍵返回),返回包含座標組的列表,格式:[(44.661290322580641, 49.951612903225794)]
            captcha = json.dumps({
                "img_size":[200,44],
                "input_points":[[i[0]/2,i[1]/2] for i in points]  #獲取的座標得除2
            })
            
        else:
            img_thread = threading.Thread(target=img.show)
            img_thread.setDaemon(True)
            img_thread.start()
            captcha = raw_input("請輸入圖片裏的驗證碼:")  #python 2.7
        r = requests.post(api,headers=headers,data={"input_text":captcha},cookies=cookies)  #先提交驗證碼結果
        print(r.text)
    return captcha,cookies
驗證碼處理

4. 加密表單數據

  拿到上述表單須要的值後,剩下的就是對錶單數據進行加密了,搜索了下encrypt,找到了以下的js代碼,經過打斷點,看到了下圖中e的值,和表單中的參數如出一轍,能夠肯定爲加密方法,簡單研究了下js代碼,實在看不懂。。。。谷歌了下大佬們的解決方案(見文末參考),發現須要將加密方法(28853行大括號截止處,對應function)拷貝出來,利用execjs模塊在python中執行js代碼便可。須要注意的是,拷貝出來的加密方法是在瀏覽器中運行的,須要去掉window,document等對象處理成node.js環境下運行的js代碼,而後安裝node.js,將execjs模塊的運行環境設置爲node.js便可以運行了。下面爲處理後的encrypt代碼和python加密方法:

function s(e) {
    return (s = "function" == typeof Symbol && "symbol" == typeof Symbol.t ? function(e) {
        return typeof e
    }
    : function(e) {
        return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e
    }
    )(e)
}
function i() {}
function h(e) {
    this.s = (2048 & e) >> 11,
    this.i = (1536 & e) >> 9,
    this.h = 511 & e,
    this.A = 511 & e
}
function A(e) {
    this.i = (3072 & e) >> 10,
    this.A = 1023 & e
}
function n(e) {
    this.n = (3072 & e) >> 10,
    this.e = (768 & e) >> 8,
    this.a = (192 & e) >> 6,
    this.s = 63 & e
}
function e(e) {
    this.i = e >> 10 & 3,
    this.h = 1023 & e
}
function a() {}
function c(e) {
    this.n = (3072 & e) >> 10,
    this.e = (768 & e) >> 8,
    this.a = (192 & e) >> 6,
    this.s = 63 & e
}
function o(e) {
    this.A = (4095 & e) >> 2,
    this.s = 3 & e
}
function r(e) {
    this.i = e >> 10 & 3,
    this.h = e >> 2 & 255,
    this.s = 3 & e
}
function k(e) {
    this.s = (4095 & e) >> 10,
    this.i = (1023 & e) >> 8,
    this.h = 1023 & e,
    this.A = 63 & e
}
function B(e) {
    this.s = (4095 & e) >> 10,
    this.n = (1023 & e) >> 8,
    this.e = (255 & e) >> 6
}
function f(e) {
    this.i = (3072 & e) >> 10,
    this.A = 1023 & e
}
function u(e) {
    this.A = 4095 & e
}
function C(e) {
    this.i = (3072 & e) >> 10
}
function b(e) {
    this.A = 4095 & e
}
function g(e) {
    this.s = (3840 & e) >> 8,
    this.i = (192 & e) >> 6,
    this.h = 63 & e
}
function G() {
    this.c = [0, 0, 0, 0],
    this.o = 0,
    this.r = [],
    this.k = [],
    this.B = [],
    this.f = [],
    this.u = [],
    this.C = !1,
    this.b = [],
    this.g = [],
    this.G = !1,
    this.Q = null,
    this.R = null,
    this.w = [],
    this.x = 0,
    this.D = {
        0: i,
        1: h,
        2: A,
        3: n,
        4: e,
        5: a,
        6: c,
        7: o,
        8: r,
        9: k,
        10: B,
        11: f,
        12: u,
        13: C,
        14: b,
        15: g
    }
}
Object.defineProperty(exports, "__esModule", {
    value: !0
});
var t = "1.1"
  , __g = {};
i.prototype.M = function(e) {
    e.G = !1
}
,
h.prototype.M = function(e) {
    switch (this.s) {
    case 0:
        e.c[this.i] = this.h;
        break;
    case 1:
        e.c[this.i] = e.k[this.A]
    }
}
,
A.prototype.M = function(e) {
    e.k[this.A] = e.c[this.i]
}
,
n.prototype.M = function(e) {
    switch (this.s) {
    case 0:
        e.c[this.n] = e.c[this.e] + e.c[this.a];
        break;
    case 1:
        e.c[this.n] = e.c[this.e] - e.c[this.a];
        break;
    case 2:
        e.c[this.n] = e.c[this.e] * e.c[this.a];
        break;
    case 3:
        e.c[this.n] = e.c[this.e] / e.c[this.a];
        break;
    case 4:
        e.c[this.n] = e.c[this.e] % e.c[this.a];
        break;
    case 5:
        e.c[this.n] = e.c[this.e] == e.c[this.a];
        break;
    case 6:
        e.c[this.n] = e.c[this.e] >= e.c[this.a];
        break;
    case 7:
        e.c[this.n] = e.c[this.e] || e.c[this.a];
        break;
    case 8:
        e.c[this.n] = e.c[this.e] && e.c[this.a];
        break;
    case 9:
        e.c[this.n] = e.c[this.e] !== e.c[this.a];
        break;
    case 10:
        e.c[this.n] = s(e.c[this.e]);
        break;
    case 11:
        e.c[this.n] = e.c[this.e]in e.c[this.a];
        break;
    case 12:
        e.c[this.n] = e.c[this.e] > e.c[this.a];
        break;
    case 13:
        e.c[this.n] = -e.c[this.e];
        break;
    case 14:
        e.c[this.n] = e.c[this.e] < e.c[this.a];
        break;
    case 15:
        e.c[this.n] = e.c[this.e] & e.c[this.a];
        break;
    case 16:
        e.c[this.n] = e.c[this.e] ^ e.c[this.a];
        break;
    case 17:
        e.c[this.n] = e.c[this.e] << e.c[this.a];
        break;
    case 18:
        e.c[this.n] = e.c[this.e] >>> e.c[this.a];
        break;
    case 19:
        e.c[this.n] = e.c[this.e] | e.c[this.a]
    }
}
,
e.prototype.M = function(e) {
    e.r.push(e.o),
    e.B.push(e.k),
    e.o = e.c[this.i],
    e.k = [];
    for (var t = 0; t < this.h; t++)
        e.k.unshift(e.f.pop());
    e.u.push(e.f),
    e.f = []
}
,
a.prototype.M = function(e) {
    e.o = e.r.pop(),
    e.k = e.B.pop(),
    e.f = e.u.pop()
}
,
c.prototype.M = function(e) {
    switch (this.s) {
    case 0:
        e.C = e.c[this.n] >= e.c[this.e];
        break;
    case 1:
        e.C = e.c[this.n] <= e.c[this.e];
        break;
    case 2:
        e.C = e.c[this.n] > e.c[this.e];
        break;
    case 3:
        e.C = e.c[this.n] < e.c[this.e];
        break;
    case 4:
        e.C = e.c[this.n] == e.c[this.e];
        break;
    case 5:
        e.C = e.c[this.n] != e.c[this.e];
        break;
    case 6:
        e.C = e.c[this.n];
        break;
    case 7:
        e.C = !e.c[this.n]
    }
}
,
o.prototype.M = function(e) {
    switch (this.s) {
    case 0:
        e.o = this.A;
        break;
    case 1:
        e.C && (e.o = this.A);
        break;
    case 2:
        e.C || (e.o = this.A);
        break;
    case 3:
        e.o = this.A,
        e.Q = null
    }
    e.C = !1
}
,
r.prototype.M = function(e) {
    switch (this.s) {
    case 0:
        for (var t = [], n = 0; n < this.h; n++)
            t.unshift(e.f.pop());
        e.c[3] = e.c[this.i](t[0], t[1]);
        break;
    case 1:
        for (var r = e.f.pop(), o = [], i = 0; i < this.h; i++)
            o.unshift(e.f.pop());
        e.c[3] = e.c[this.i][r](o[0], o[1]);
        break;
    case 2:
        for (var a = [], c = 0; c < this.h; c++)
            a.unshift(e.f.pop());
        e.c[3] = new e.c[this.i](a[0],a[1])
    }
}
,
k.prototype.M = function(e) {
    switch (this.s) {
    case 0:
        e.f.push(e.c[this.i]);
        break;
    case 1:
        e.f.push(this.h);
        break;
    case 2:
        e.f.push(e.k[this.A]);
        break;
    case 3:
        e.f.push(e.g[this.A])
    }
}
,
B.prototype.M = function(t) {
    switch (this.s) {
    case 0:
        var s = t.f.pop();
        t.c[this.n] = t.c[this.e][s];
        break;
    case 1:
        var i = t.f.pop()
          , h = t.f.pop();
        t.c[this.e][i] = h;
        break;
    case 2:
        var A = t.f.pop();
        if(A === 'window') {
            A = {
                encodeURIComponent: function (url) {
                    return encodeURIComponent(url)
                }
            }
        } else if (A === 'navigator') {
            A = {
                'userAgent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ' +
                    '(KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'
            }
        }
        t.c[this.n] = eval(A)
    }
}
,
f.prototype.M = function(e) {
    e.c[this.i] = e.g[this.A]
}
,
u.prototype.M = function(e) {
    e.Q = this.A
}
,
C.prototype.M = function(e) {
    throw e.c[this.i]
}
,
b.prototype.M = function(e) {
    var t = this
      , n = [0];
    e.k.forEach(function(e) {
        n.push(e)
    });
    var r = function(r) {
        var o = new G;
        return o.k = n,
        o.k[0] = r,
        o.J(e.b, t.A, e.g, e.w),
        o.c[3]
    };
    r.toString = function() {
        return "() { [native code] }"
    }
    ,
    e.c[3] = r
}
,
g.prototype.M = function(e) {
    switch (this.s) {
    case 0:
        for (var t = {}, n = 0; n < this.h; n++) {
            var r = e.f.pop();
            t[e.f.pop()] = r
        }
        e.c[this.i] = t;
        break;
    case 1:
        for (var o = [], i = 0; i < this.h; i++)
            o.unshift(e.f.pop());
        e.c[this.i] = o
    }
}
,
G.prototype.v = function(e) {
    for (var t = Buffer.from(e, 'base64').toString('binary'), n = [], r = 0; r < t.length - 1; r += 2)
        n.push(t.charCodeAt(r) << 8 | t.charCodeAt(r + 1));
    this.b = n
}
,
G.prototype.y = function(e) {
    for (var t = Buffer.from(e, 'base64').toString('binary'), n = 66, r = [], o = 0; o < t.length; o++) {
        var i = 24 ^ t.charCodeAt(o) ^ n;
        r.push(String.fromCharCode(i)),
        n = i
    }
    return r.join("")
}
,
G.prototype.F = function(e) {
    var t = this;
    this.g = e.map(function(e) {
        return "string" == typeof e ? t.y(e) : e
    })
}
,
G.prototype.J = function(e, t, n) {
    for (t = t || 0,
    n = n || [],
    this.o = t,
    "string" == typeof e ? (this.F(n),
    this.v(e)) : (this.b = e,
    this.g = n),
    this.G = !0,
    this.x = Date.now(); this.G; ) {
        var r = this.b[this.o++];
        if ("number" != typeof r)
            break;
        var o = Date.now();
        if (500 < o - this.x)
            return;
        this.x = o;
        try {
            this.M(r)
        } catch (e) {
            if (this.R = e,
            !this.Q)
                throw "execption at " + this.o + ": " + e;
            this.o = this.Q
        }
    }
}
,
G.prototype.M = function(e) {
    var t = (61440 & e) >> 12;
    new this.D[t](e).M(this)
}
,
(new G).J("4AeTAJwAqACcAaQAAAAYAJAAnAKoAJwDgAWTACwAnAKoACACGAESOTRHkQAkAbAEIAMYAJwFoAASAzREJAQYBBIBNEVkBnCiGAC0BjRAJAAYBBICNEVkBnDGGAC0BzRAJACwCJAAnAmoAJwKoACcC4ABnAyMBRAAMwZgBnESsA0aADRAkQAkABgCnA6gABoCnA+hQDRHGAKcEKAAMQdgBnFasBEaADRAkQAkABgCnBKgABoCnBOhQDRHZAZxkrAUGgA0QJEAJAAYApwVoABgBnG6sBYaADRAkQAkABgCnBegAGAGceKwGBoANECRACQAnAmoAJwZoABgBnIOsBoaADRAkQAkABgCnBugABoCnByhQDRHZAZyRrAdGgA0QJEAJAAQACAFsB4gBhgAnAWgABIBNEEkBxgHEgA0RmQGdJoQCBoFFAE5gCgFFAQ5hDSCJAgYB5AAGACcH4AFGAEaCDRSEP8xDzMQIAkQCBoFFAE5gCgFFAQ5hDSCkQAkCBgBGgg0UhD/MQ+QACAIGAkaBxQBOYGSABoAnB+EBRoIN1AUCDmRNJMkCRAIGgUUATmAKAUUBDmENIKRACQIGAEaCDRSEP8xD5AAIAgYCRoHFAI5gZIAGgCcH4QFGgg3UBQQOZE0kyQJGAMaCRQ/OY+SABoGnCCEBTTAJAMYAxoJFAY5khI/Nk+RABoGnCCEBTTAJAMYAxoJFAw5khI/Nk+RABoGnCCEBTTAJAMYAxoJFBI5khI/Nk+RABoGnCCEBTTAJAMYBxIDNEEkB3JsHgNQAA==", 0, ["BRgg", "BSITFQkTERw=", "LQYfEhMA", "PxMVFBMZKB8DEjQaBQcZExMC", "", "NhETEQsE", "Whg=", "Wg==", "MhUcHRARDhg=", "NBcPBxYeDQMF", "Lx4ODys+GhMC", "LgM7OwAKDyk6Cg4=", "Mx8SGQUvMQ==", "SA==", "ORoVGCQgERcCAxo=", "BTcAERcCAxo=", "BRg3ABEXAgMaFAo=", "SQ==", "OA8LGBsP", "GC8LGBsP", "Tg==", "PxAcBQ==", "Tw==", "KRsJDgE=", "TA==", "LQofHg4DBwsP", "TQ==", "PhMaNCwZAxoUDQUeGQ==", "PhMaNCwZAxoUDQUeGTU0GQIeBRsYEQ8=", "Qg==", "BWpUGxkfGRsZFxkbGR8ZGxkHGRsZHxkbGRcZG1MbGR8ZGxkXGRFpGxkfGRsZFxkbGR8ZGxkHGRsZHxkbGRcZGw==", "ORMRCyk0Exk8LQ==", "ORMRCyst"]);
var Q = function(e) {
    return __g._encrypt(e)
};
encrypt.js
#準備表單數據
    timestamp = int(1000*time.time())
    data_dict = {
        "captcha": "",
        "client_id": "c3cef7c66a1843f8b3a9e6a1e3160e20",
        "grant_type": "password",
        "lang": "en",
        "password": "你的密碼",
        "ref_source": "homepage",
        "signature": "",
        "source": "com.zhihu.web",
        "timestamp": timestamp,
        "username": "你的用戶名",
        "utm_source": "",
    }
#將表單數據加密
    with open("encrypt.js",'r') as f:
        #os.environ["EXECJS_RUNTIME"] = "Node"
        # os.environ["NODE_PATH"] = r"D:\nodejs\node_modules"
        #print execjs.get().name
        js = execjs.compile(f.read().decode("utf-8"))  #傳入unicode字符
        data = js.call(u'Q',urlencode(data_dict)) #data_dict爲表單數據
表單加密

 

5. 加密數據提交

  拿到全部數據後,能夠提交post請求了,須要注意的有三個地方:

    1.表單中參數的大小寫和拼寫要注意了 (我開始將client_id寫成了clientId,報錯找不到client_id參數)

    2. 請求頭headers必須須要"content-type":",'x-zse-83',"x-xsrftoken"三個參數

    3. 須要帶上cookie,最主要的是cookie中的cookies["capsion_ticket"]不能少,能夠利用獲取驗證碼時返回的cookie

  最後完整代碼以下:

#coding:utf-8

#登錄並爬取知乎

import requests
import time 
import hmac
import hashlib
from urllib import urlencode
import execjs #安裝PyExecJS模塊
import os
import json
import re
import base64
from PIL import Image
import matplotlib.pyplot as plt
import threading



def get_signature(grantType,clientId,source,timestamp):
    h = hmac.new("d1b964811afb40118a12068ff74a12f4","",hashlib.sha1)
    h.update(grantType+clientId+source+str(timestamp))
    return h.hexdigest()

def get_captcha(lang,headers):
    if lang=="cn":
        api = "https://www.zhihu.com/api/v3/oauth/captcha?lang=cn"
    else:
        api = "https://www.zhihu.com/api/v3/oauth/captcha?lang=en"
        
    ret = requests.get(api,headers=headers)
    cookies = ret.cookies
    show_captcha = re.search("true",ret.text)
    captcha=""
    if show_captcha:
        img_res = requests.put(api,headers=headers,cookies=cookies)  #得帶上第一步的cookie,不然返回,{u'code': 120002, u'name': u'ERR_CAPSION_TICKET_NOT_FOUND'}
        img_json = json.loads(img_res.text)
        img_data = img_json["img_base64"].replace("\n","")
        with open("captcha.jpg","wb") as i:
            i.write(base64.b64decode(img_data))
        img = Image.open("captcha.jpg")
        if lang=="cn":
            plt.imshow(img)
            print("點擊圖片中全部倒立的漢字,在命令行中按回車鍵提交")
            points = plt.ginput(7) #阻塞點擊七次後返回(或者中途點擊回車鍵返回),返回包含座標組的列表,格式:[(44.661290322580641, 49.951612903225794)]
            captcha = json.dumps({
                "img_size":[200,44],
                "input_points":[[i[0]/2,i[1]/2] for i in points]  #獲取的座標得除2
            })
            
        else:
            img_thread = threading.Thread(target=img.show)
            img_thread.setDaemon(True)
            img_thread.start()
            captcha = raw_input("請輸入圖片裏的驗證碼:")  #python 2.7
        r = requests.post(api,headers=headers,data={"input_text":captcha},cookies=cookies)  #先提交驗證碼結果
        print(r.text)
    return captcha,cookies
def get_xsrf(headers):
    url="https://www.zhihu.com/"
    r = requests.get(url,headers=headers,allow_redirects=False)  #禁止重定向時,cookies裏面有xsrf參數
    xsrf = r.cookies["_xsrf"]    
    
def login(lang):
    headers={"User-Agent":"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36",}
    
    #準備表單數據
    timestamp = int(1000*time.time())
    data_dict = {
        "captcha": "",
        "client_id": "c3cef7c66a1843f8b3a9e6a1e3160e20",
        "grant_type": "password",
        "lang": "en",
        "password": "xxxxx",
        "ref_source": "homepage",
        "signature": "",
        "source": "com.zhihu.web",
        "timestamp": timestamp,
        "username": "xxxxxxxx",
        "utm_source": "",
    }
    data_dict["signature"] = get_signature(data_dict["grant_type"],data_dict["client_id"],data_dict["source"],timestamp)
    data_dict["captcha"],cookies = get_captcha(lang,headers)
    
    #將表單數據加密
    with open("encrypt.js",'r') as f:
        #os.environ["EXECJS_RUNTIME"] = "Node"
        # os.environ["NODE_PATH"] = r"D:\nodejs\node_modules"
        #print execjs.get().name
        js = execjs.compile(f.read().decode("utf-8"))  #傳入unicode字符
        data = js.call(u'Q',urlencode(data_dict)) #data_dict爲表單數據
        print(data)
    
    #準備請求頭
    xsrf = get_xsrf(headers)
    header={
        "content-type":"application/x-www-form-urlencoded",
        #"Referer":"https://www.zhihu.com/signin",
        'x-zse-83': '3_1.1',
        "x-xsrftoken":xsrf,    
    }
    headers.update(header)
    sign_url = "https://www.zhihu.com/api/v3/oauth/sign_in"
    response = requests.post(url=sign_url,headers=headers,data=data,cookies=cookies)   #cookies["capsion_ticket"]不能少
    print(response.status_code)
    print(response.text)
    
if __name__=="__main__":
    login("cn")  #也能夠爲en
知乎登錄
function s(e) {
    return (s = "function" == typeof Symbol && "symbol" == typeof Symbol.t ? function(e) {
        return typeof e
    }
    : function(e) {
        return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e
    }
    )(e)
}
function i() {}
function h(e) {
    this.s = (2048 & e) >> 11,
    this.i = (1536 & e) >> 9,
    this.h = 511 & e,
    this.A = 511 & e
}
function A(e) {
    this.i = (3072 & e) >> 10,
    this.A = 1023 & e
}
function n(e) {
    this.n = (3072 & e) >> 10,
    this.e = (768 & e) >> 8,
    this.a = (192 & e) >> 6,
    this.s = 63 & e
}
function e(e) {
    this.i = e >> 10 & 3,
    this.h = 1023 & e
}
function a() {}
function c(e) {
    this.n = (3072 & e) >> 10,
    this.e = (768 & e) >> 8,
    this.a = (192 & e) >> 6,
    this.s = 63 & e
}
function o(e) {
    this.A = (4095 & e) >> 2,
    this.s = 3 & e
}
function r(e) {
    this.i = e >> 10 & 3,
    this.h = e >> 2 & 255,
    this.s = 3 & e
}
function k(e) {
    this.s = (4095 & e) >> 10,
    this.i = (1023 & e) >> 8,
    this.h = 1023 & e,
    this.A = 63 & e
}
function B(e) {
    this.s = (4095 & e) >> 10,
    this.n = (1023 & e) >> 8,
    this.e = (255 & e) >> 6
}
function f(e) {
    this.i = (3072 & e) >> 10,
    this.A = 1023 & e
}
function u(e) {
    this.A = 4095 & e
}
function C(e) {
    this.i = (3072 & e) >> 10
}
function b(e) {
    this.A = 4095 & e
}
function g(e) {
    this.s = (3840 & e) >> 8,
    this.i = (192 & e) >> 6,
    this.h = 63 & e
}
function G() {
    this.c = [0, 0, 0, 0],
    this.o = 0,
    this.r = [],
    this.k = [],
    this.B = [],
    this.f = [],
    this.u = [],
    this.C = !1,
    this.b = [],
    this.g = [],
    this.G = !1,
    this.Q = null,
    this.R = null,
    this.w = [],
    this.x = 0,
    this.D = {
        0: i,
        1: h,
        2: A,
        3: n,
        4: e,
        5: a,
        6: c,
        7: o,
        8: r,
        9: k,
        10: B,
        11: f,
        12: u,
        13: C,
        14: b,
        15: g
    }
}
Object.defineProperty(exports, "__esModule", {
    value: !0
});
var t = "1.1"
  , __g = {};
i.prototype.M = function(e) {
    e.G = !1
}
,
h.prototype.M = function(e) {
    switch (this.s) {
    case 0:
        e.c[this.i] = this.h;
        break;
    case 1:
        e.c[this.i] = e.k[this.A]
    }
}
,
A.prototype.M = function(e) {
    e.k[this.A] = e.c[this.i]
}
,
n.prototype.M = function(e) {
    switch (this.s) {
    case 0:
        e.c[this.n] = e.c[this.e] + e.c[this.a];
        break;
    case 1:
        e.c[this.n] = e.c[this.e] - e.c[this.a];
        break;
    case 2:
        e.c[this.n] = e.c[this.e] * e.c[this.a];
        break;
    case 3:
        e.c[this.n] = e.c[this.e] / e.c[this.a];
        break;
    case 4:
        e.c[this.n] = e.c[this.e] % e.c[this.a];
        break;
    case 5:
        e.c[this.n] = e.c[this.e] == e.c[this.a];
        break;
    case 6:
        e.c[this.n] = e.c[this.e] >= e.c[this.a];
        break;
    case 7:
        e.c[this.n] = e.c[this.e] || e.c[this.a];
        break;
    case 8:
        e.c[this.n] = e.c[this.e] && e.c[this.a];
        break;
    case 9:
        e.c[this.n] = e.c[this.e] !== e.c[this.a];
        break;
    case 10:
        e.c[this.n] = s(e.c[this.e]);
        break;
    case 11:
        e.c[this.n] = e.c[this.e]in e.c[this.a];
        break;
    case 12:
        e.c[this.n] = e.c[this.e] > e.c[this.a];
        break;
    case 13:
        e.c[this.n] = -e.c[this.e];
        break;
    case 14:
        e.c[this.n] = e.c[this.e] < e.c[this.a];
        break;
    case 15:
        e.c[this.n] = e.c[this.e] & e.c[this.a];
        break;
    case 16:
        e.c[this.n] = e.c[this.e] ^ e.c[this.a];
        break;
    case 17:
        e.c[this.n] = e.c[this.e] << e.c[this.a];
        break;
    case 18:
        e.c[this.n] = e.c[this.e] >>> e.c[this.a];
        break;
    case 19:
        e.c[this.n] = e.c[this.e] | e.c[this.a]
    }
}
,
e.prototype.M = function(e) {
    e.r.push(e.o),
    e.B.push(e.k),
    e.o = e.c[this.i],
    e.k = [];
    for (var t = 0; t < this.h; t++)
        e.k.unshift(e.f.pop());
    e.u.push(e.f),
    e.f = []
}
,
a.prototype.M = function(e) {
    e.o = e.r.pop(),
    e.k = e.B.pop(),
    e.f = e.u.pop()
}
,
c.prototype.M = function(e) {
    switch (this.s) {
    case 0:
        e.C = e.c[this.n] >= e.c[this.e];
        break;
    case 1:
        e.C = e.c[this.n] <= e.c[this.e];
        break;
    case 2:
        e.C = e.c[this.n] > e.c[this.e];
        break;
    case 3:
        e.C = e.c[this.n] < e.c[this.e];
        break;
    case 4:
        e.C = e.c[this.n] == e.c[this.e];
        break;
    case 5:
        e.C = e.c[this.n] != e.c[this.e];
        break;
    case 6:
        e.C = e.c[this.n];
        break;
    case 7:
        e.C = !e.c[this.n]
    }
}
,
o.prototype.M = function(e) {
    switch (this.s) {
    case 0:
        e.o = this.A;
        break;
    case 1:
        e.C && (e.o = this.A);
        break;
    case 2:
        e.C || (e.o = this.A);
        break;
    case 3:
        e.o = this.A,
        e.Q = null
    }
    e.C = !1
}
,
r.prototype.M = function(e) {
    switch (this.s) {
    case 0:
        for (var t = [], n = 0; n < this.h; n++)
            t.unshift(e.f.pop());
        e.c[3] = e.c[this.i](t[0], t[1]);
        break;
    case 1:
        for (var r = e.f.pop(), o = [], i = 0; i < this.h; i++)
            o.unshift(e.f.pop());
        e.c[3] = e.c[this.i][r](o[0], o[1]);
        break;
    case 2:
        for (var a = [], c = 0; c < this.h; c++)
            a.unshift(e.f.pop());
        e.c[3] = new e.c[this.i](a[0],a[1])
    }
}
,
k.prototype.M = function(e) {
    switch (this.s) {
    case 0:
        e.f.push(e.c[this.i]);
        break;
    case 1:
        e.f.push(this.h);
        break;
    case 2:
        e.f.push(e.k[this.A]);
        break;
    case 3:
        e.f.push(e.g[this.A])
    }
}
,
B.prototype.M = function(t) {
    switch (this.s) {
    case 0:
        var s = t.f.pop();
        t.c[this.n] = t.c[this.e][s];
        break;
    case 1:
        var i = t.f.pop()
          , h = t.f.pop();
        t.c[this.e][i] = h;
        break;
    case 2:
        var A = t.f.pop();
        if(A === 'window') {
            A = {
                encodeURIComponent: function (url) {
                    return encodeURIComponent(url)
                }
            }
        } else if (A === 'navigator') {
            A = {
                'userAgent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ' +
                    '(KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'
            }
        }
        t.c[this.n] = eval(A)
    }
}
,
f.prototype.M = function(e) {
    e.c[this.i] = e.g[this.A]
}
,
u.prototype.M = function(e) {
    e.Q = this.A
}
,
C.prototype.M = function(e) {
    throw e.c[this.i]
}
,
b.prototype.M = function(e) {
    var t = this
      , n = [0];
    e.k.forEach(function(e) {
        n.push(e)
    });
    var r = function(r) {
        var o = new G;
        return o.k = n,
        o.k[0] = r,
        o.J(e.b, t.A, e.g, e.w),
        o.c[3]
    };
    r.toString = function() {
        return "() { [native code] }"
    }
    ,
    e.c[3] = r
}
,
g.prototype.M = function(e) {
    switch (this.s) {
    case 0:
        for (var t = {}, n = 0; n < this.h; n++) {
            var r = e.f.pop();
            t[e.f.pop()] = r
        }
        e.c[this.i] = t;
        break;
    case 1:
        for (var o = [], i = 0; i < this.h; i++)
            o.unshift(e.f.pop());
        e.c[this.i] = o
    }
}
,
G.prototype.v = function(e) {
    for (var t = Buffer.from(e, 'base64').toString('binary'), n = [], r = 0; r < t.length - 1; r += 2)
        n.push(t.charCodeAt(r) << 8 | t.charCodeAt(r + 1));
    this.b = n
}
,
G.prototype.y = function(e) {
    for (var t = Buffer.from(e, 'base64').toString('binary'), n = 66, r = [], o = 0; o < t.length; o++) {
        var i = 24 ^ t.charCodeAt(o) ^ n;
        r.push(String.fromCharCode(i)),
        n = i
    }
    return r.join("")
}
,
G.prototype.F = function(e) {
    var t = this;
    this.g = e.map(function(e) {
        return "string" == typeof e ? t.y(e) : e
    })
}
,
G.prototype.J = function(e, t, n) {
    for (t = t || 0,
    n = n || [],
    this.o = t,
    "string" == typeof e ? (this.F(n),
    this.v(e)) : (this.b = e,
    this.g = n),
    this.G = !0,
    this.x = Date.now(); this.G; ) {
        var r = this.b[this.o++];
        if ("number" != typeof r)
            break;
        var o = Date.now();
        if (500 < o - this.x)
            return;
        this.x = o;
        try {
            this.M(r)
        } catch (e) {
            if (this.R = e,
            !this.Q)
                throw "execption at " + this.o + ": " + e;
            this.o = this.Q
        }
    }
}
,
G.prototype.M = function(e) {
    var t = (61440 & e) >> 12;
    new this.D[t](e).M(this)
}
,
(new G).J("4AeTAJwAqACcAaQAAAAYAJAAnAKoAJwDgAWTACwAnAKoACACGAESOTRHkQAkAbAEIAMYAJwFoAASAzREJAQYBBIBNEVkBnCiGAC0BjRAJAAYBBICNEVkBnDGGAC0BzRAJACwCJAAnAmoAJwKoACcC4ABnAyMBRAAMwZgBnESsA0aADRAkQAkABgCnA6gABoCnA+hQDRHGAKcEKAAMQdgBnFasBEaADRAkQAkABgCnBKgABoCnBOhQDRHZAZxkrAUGgA0QJEAJAAYApwVoABgBnG6sBYaADRAkQAkABgCnBegAGAGceKwGBoANECRACQAnAmoAJwZoABgBnIOsBoaADRAkQAkABgCnBugABoCnByhQDRHZAZyRrAdGgA0QJEAJAAQACAFsB4gBhgAnAWgABIBNEEkBxgHEgA0RmQGdJoQCBoFFAE5gCgFFAQ5hDSCJAgYB5AAGACcH4AFGAEaCDRSEP8xDzMQIAkQCBoFFAE5gCgFFAQ5hDSCkQAkCBgBGgg0UhD/MQ+QACAIGAkaBxQBOYGSABoAnB+EBRoIN1AUCDmRNJMkCRAIGgUUATmAKAUUBDmENIKRACQIGAEaCDRSEP8xD5AAIAgYCRoHFAI5gZIAGgCcH4QFGgg3UBQQOZE0kyQJGAMaCRQ/OY+SABoGnCCEBTTAJAMYAxoJFAY5khI/Nk+RABoGnCCEBTTAJAMYAxoJFAw5khI/Nk+RABoGnCCEBTTAJAMYAxoJFBI5khI/Nk+RABoGnCCEBTTAJAMYBxIDNEEkB3JsHgNQAA==", 0, ["BRgg", "BSITFQkTERw=", "LQYfEhMA", "PxMVFBMZKB8DEjQaBQcZExMC", "", "NhETEQsE", "Whg=", "Wg==", "MhUcHRARDhg=", "NBcPBxYeDQMF", "Lx4ODys+GhMC", "LgM7OwAKDyk6Cg4=", "Mx8SGQUvMQ==", "SA==", "ORoVGCQgERcCAxo=", "BTcAERcCAxo=", "BRg3ABEXAgMaFAo=", "SQ==", "OA8LGBsP", "GC8LGBsP", "Tg==", "PxAcBQ==", "Tw==", "KRsJDgE=", "TA==", "LQofHg4DBwsP", "TQ==", "PhMaNCwZAxoUDQUeGQ==", "PhMaNCwZAxoUDQUeGTU0GQIeBRsYEQ8=", "Qg==", "BWpUGxkfGRsZFxkbGR8ZGxkHGRsZHxkbGRcZG1MbGR8ZGxkXGRFpGxkfGRsZFxkbGR8ZGxkHGRsZHxkbGRcZGw==", "ORMRCyk0Exk8LQ==", "ORMRCyst"]);
var Q = function(e) {
    return __g._encrypt(e)
};
encrypt.js

 

參考: https://zhuanlan.zhihu.com/p/57375111

   https://zhuanlan.zhihu.com/p/34073256

相關文章
相關標籤/搜索