常规更新
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
+31
-29
@@ -8,38 +8,39 @@ import hashlib
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
|
||||
class Leipin(object):
|
||||
def __init__(self, username, password):
|
||||
self.username = username
|
||||
self.password = password
|
||||
self.headers = {
|
||||
'Accept':'application/json, text/javascript, */*; q=0.01',
|
||||
'Accept-Encoding':'gzip, deflate, sdch',
|
||||
'Accept-Language':'zh-CN,zh;q=0.8',
|
||||
'Connection':'keep-alive',
|
||||
'Content-Type':'application/x-www-form-urlencoded',
|
||||
'Host':'passport.liepin.com',
|
||||
'User-Agent': "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)",
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'Upgrade-Insecure-Requests':'1',
|
||||
}
|
||||
'Accept': 'application/json, text/javascript, */*; q=0.01',
|
||||
'Accept-Encoding': 'gzip, deflate, sdch',
|
||||
'Accept-Language': 'zh-CN,zh;q=0.8',
|
||||
'Connection': 'keep-alive',
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'Host': 'passport.liepin.com',
|
||||
'User-Agent': "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)",
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'Upgrade-Insecure-Requests': '1',
|
||||
}
|
||||
self.proxies = {
|
||||
'HTTP':'http://120.198.231.88:80',
|
||||
#'HTTP':'http://222.174.71.46:9999',
|
||||
} # 测试所用代理
|
||||
'HTTP': 'http://120.198.231.88:80',
|
||||
# 'HTTP':'http://222.174.71.46:9999',
|
||||
} # 测试所用代理
|
||||
self.session = requests.session()
|
||||
self.accountUrl = 'https://passport.liepin.com/h/account'
|
||||
self.loginUrl = 'https://passport.liepin.com/h/login.json'
|
||||
self.Dir = 'E:\\python\\authcode.jpg' #authcode folder 根据自己情况选择文件夹
|
||||
self.Dir = 'E:\\python\\authcode.jpg' # authcode folder 根据自己情况选择文件夹
|
||||
|
||||
def _md5(self):
|
||||
md5 = hashlib.md5()
|
||||
md5 = hashlib.md5()
|
||||
md5.update(str.encode(password))
|
||||
psw = md5.hexdigest()
|
||||
return psw
|
||||
|
||||
def _getAuthcode(self):
|
||||
r = self.session.get(self.accountUrl,headers = self.headers,timeout = 10, proxies = self.proxies)
|
||||
r = self.session.get(self.accountUrl, headers=self.headers, timeout=10, proxies=self.proxies)
|
||||
page = BeautifulSoup(r.text)
|
||||
selector = page.find_all('div', class_="ui-tab-toggle hide")[0]
|
||||
imageUrl = selector.select('div > img')[0]['src']
|
||||
@@ -52,23 +53,24 @@ class Leipin(object):
|
||||
return authcode
|
||||
|
||||
def login(self):
|
||||
payload ={
|
||||
'user_login':self.username,
|
||||
'isMd5':1,
|
||||
'user_pwd': self._md5(),
|
||||
'user_kind':2, #根据你是否为正式会员而定,根据自身情况可能需要修改
|
||||
'verifycode':self._getAuthcode(),
|
||||
'url':'',
|
||||
}
|
||||
payload = {
|
||||
'user_login': self.username,
|
||||
'isMd5': 1,
|
||||
'user_pwd': self._md5(),
|
||||
'user_kind': 2, # 根据你是否为正式会员而定,根据自身情况可能需要修改
|
||||
'verifycode': self._getAuthcode(),
|
||||
'url': '',
|
||||
}
|
||||
del self.headers['Upgrade-Insecure-Requests']
|
||||
self.headers['Origin'] = 'https://passport.liepin.com'
|
||||
self.headers['Referer']='https://passport.liepin.com/h/account'
|
||||
response = self.session.post(self.loginUrl, headers=self.headers, data = payload, timeout =10, proxies = self.proxies ,allow_redirects =False)
|
||||
self.headers['Referer'] = 'https://passport.liepin.com/h/account'
|
||||
response = self.session.post(self.loginUrl, headers=self.headers, data=payload, timeout=10,
|
||||
proxies=self.proxies, allow_redirects=False)
|
||||
return response.status_code, response.text
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
userName = input("plz input username:")
|
||||
password = input("plz input password:")
|
||||
lp = Leipin(userName,password)
|
||||
print (lp.login())
|
||||
lp = Leipin(userName, password)
|
||||
print(lp.login())
|
||||
|
||||
Vendored
BIN
Binary file not shown.
@@ -0,0 +1,430 @@
|
||||
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)
|
||||
};
|
||||
Executable → Regular
+199
-71
@@ -1,77 +1,205 @@
|
||||
import requests , time
|
||||
import hmac ,json
|
||||
from bs4 import BeautifulSoup
|
||||
from hashlib import sha1
|
||||
# -*- coding: utf-8 -*-
|
||||
import threading
|
||||
|
||||
"""
|
||||
info:
|
||||
author:CriseLYJ
|
||||
github:https://github.com/CriseLYJ/
|
||||
update_time:2019-3-6
|
||||
"""
|
||||
|
||||
def get_captcha(data,need_cap):
|
||||
''' 处理验证码 '''
|
||||
if need_cap is False:
|
||||
return
|
||||
with open('captcha.gif','wb') as fb:
|
||||
fb.write(data)
|
||||
return input('captcha:')
|
||||
|
||||
def get_signature(grantType,clientId,source,timestamp):
|
||||
''' 处理签名 '''
|
||||
|
||||
hm = hmac.new(b'd1b964811afb40118a12068ff74a12f4',None,sha1)
|
||||
hm.update(str.encode(grantType))
|
||||
hm.update(str.encode(clientId))
|
||||
hm.update(str.encode(source))
|
||||
hm.update(str.encode(timestamp))
|
||||
|
||||
return str(hm.hexdigest())
|
||||
|
||||
|
||||
|
||||
def login(username,password,oncaptcha,sessiona,headers):
|
||||
''' 处理登录 '''
|
||||
|
||||
resp1 = sessiona.get('https://www.zhihu.com/signin',headers=headers) # 拿cookie:_xsrf
|
||||
resp2 = sessiona.get('https://www.zhihu.com/api/v3/oauth/captcha?lang=cn',headers=headers) # 拿cookie:capsion_ticket
|
||||
need_cap = json.loads(resp2.text)["show_captcha"] # {"show_captcha":false} 表示不用验证码
|
||||
|
||||
grantType = 'password'
|
||||
clientId = 'c3cef7c66a1843f8b3a9e6a1e3160e20'
|
||||
source ='com.zhihu.web'
|
||||
timestamp = str((time.time()*1000)).split('.')[0] # 签名只按这个时间戳变化
|
||||
|
||||
captcha_content = sessiona.get('https://www.zhihu.com/captcha.gif?r=%d&type=login'%(time.time()*1000),headers=headers).content
|
||||
|
||||
data = {
|
||||
"client_id":clientId,
|
||||
"grant_type":grantType,
|
||||
"timestamp":timestamp,
|
||||
"source":source,
|
||||
"signature": get_signature(grantType,clientId,source,timestamp), # 获取签名
|
||||
"username":username,
|
||||
"password":password,
|
||||
"lang":"cn",
|
||||
"captcha":oncaptcha(captcha_content,need_cap), # 获取图片验证码
|
||||
"ref_source":"other_",
|
||||
"utm_source":""
|
||||
}
|
||||
|
||||
print("**2**: "+str(data))
|
||||
print("-"*50)
|
||||
resp = sessiona.post('https://www.zhihu.com/api/v3/oauth/sign_in',data,headers=headers).content
|
||||
print(BeautifulSoup(resp,'html.parser'))
|
||||
|
||||
print("-"*50)
|
||||
return resp
|
||||
|
||||
if __name__ == "__main__":
|
||||
sessiona = requests.Session()
|
||||
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0','authorization':'oauth c3cef7c66a1843f8b3a9e6a1e3160e20'}
|
||||
# 用户名密码换自己的就好了
|
||||
phone_num = input('请输入你的用户名')
|
||||
password = input('请输入你的密码')
|
||||
login(phone_num, password,get_captcha,sessiona,headers)
|
||||
resp = sessiona.get('https://www.zhihu.com/inbox',headers=headers) # 登录进去了,可以看私信了
|
||||
print(BeautifulSoup(resp.content ,'html.parser'))
|
||||
import base64
|
||||
import hashlib
|
||||
import hmac
|
||||
import json
|
||||
import re
|
||||
import time
|
||||
from http import cookiejar
|
||||
from urllib.parse import urlencode
|
||||
|
||||
import execjs
|
||||
import requests
|
||||
from PIL import Image
|
||||
|
||||
|
||||
class ZhihuAccount(object):
|
||||
|
||||
def __init__(self, username: str = None, password: str = None):
|
||||
self.username = username
|
||||
self.password = password
|
||||
|
||||
self.login_data = {
|
||||
'client_id': 'c3cef7c66a1843f8b3a9e6a1e3160e20',
|
||||
'grant_type': 'password',
|
||||
'source': 'com.zhihu.web',
|
||||
'username': '',
|
||||
'password': '',
|
||||
'lang': 'en',
|
||||
'ref_source': 'homepage',
|
||||
'utm_source': ''
|
||||
}
|
||||
self.session = requests.session()
|
||||
self.session.headers = {
|
||||
'accept-encoding': 'gzip, deflate, br',
|
||||
'Host': 'www.zhihu.com',
|
||||
'Referer': 'https://www.zhihu.com/',
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '
|
||||
'(KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'
|
||||
}
|
||||
self.session.cookies = cookiejar.LWPCookieJar(filename='./cookies.txt')
|
||||
|
||||
def login(self, captcha_lang: str = 'en', load_cookies: bool = True):
|
||||
"""
|
||||
模拟登录知乎
|
||||
:param captcha_lang: 验证码类型 'en' or 'cn'
|
||||
:param load_cookies: 是否读取上次保存的 Cookies
|
||||
:return: bool
|
||||
若在 PyCharm 下使用中文验证出现无法点击的问题,
|
||||
需要在 Settings / Tools / Python Scientific / Show Plots in Toolwindow,取消勾选
|
||||
"""
|
||||
if load_cookies and self.load_cookies():
|
||||
print('读取 Cookies 文件')
|
||||
if self.check_login():
|
||||
print('登录成功')
|
||||
return True
|
||||
print('Cookies 已过期')
|
||||
|
||||
self._check_user_pass()
|
||||
self.login_data.update({
|
||||
'username': self.username,
|
||||
'password': self.password,
|
||||
'lang': captcha_lang
|
||||
})
|
||||
|
||||
timestamp = int(time.time() * 1000)
|
||||
self.login_data.update({
|
||||
'captcha': self._get_captcha(self.login_data['lang']),
|
||||
'timestamp': timestamp,
|
||||
'signature': self._get_signature(timestamp)
|
||||
})
|
||||
|
||||
headers = self.session.headers.copy()
|
||||
headers.update({
|
||||
'content-type': 'application/x-www-form-urlencoded',
|
||||
'x-zse-83': '3_1.1',
|
||||
'x-xsrftoken': self._get_xsrf()
|
||||
})
|
||||
data = self._encrypt(self.login_data)
|
||||
login_api = 'https://www.zhihu.com/api/v3/oauth/sign_in'
|
||||
resp = self.session.post(login_api, data=data, headers=headers)
|
||||
if 'error' in resp.text:
|
||||
print(json.loads(resp.text)['error'])
|
||||
if self.check_login():
|
||||
print('登录成功')
|
||||
return True
|
||||
print('登录失败')
|
||||
return False
|
||||
|
||||
def load_cookies(self):
|
||||
"""
|
||||
读取 Cookies 文件加载到 Session
|
||||
:return: bool
|
||||
"""
|
||||
try:
|
||||
self.session.cookies.load(ignore_discard=True)
|
||||
return True
|
||||
except FileNotFoundError:
|
||||
return False
|
||||
|
||||
def check_login(self):
|
||||
"""
|
||||
检查登录状态,访问登录页面出现跳转则是已登录,
|
||||
如登录成功保存当前 Cookies
|
||||
:return: bool
|
||||
"""
|
||||
login_url = 'https://www.zhihu.com/signup'
|
||||
resp = self.session.get(login_url, allow_redirects=False)
|
||||
if resp.status_code == 302:
|
||||
self.session.cookies.save()
|
||||
return True
|
||||
return False
|
||||
|
||||
def _get_xsrf(self):
|
||||
"""
|
||||
从登录页面获取 xsrf
|
||||
:return: str
|
||||
"""
|
||||
self.session.get('https://www.zhihu.com/', allow_redirects=False)
|
||||
for c in self.session.cookies:
|
||||
if c.name == '_xsrf':
|
||||
return c.value
|
||||
raise AssertionError('获取 xsrf 失败')
|
||||
|
||||
def _get_captcha(self, lang: str):
|
||||
"""
|
||||
请求验证码的 API 接口,无论是否需要验证码都需要请求一次
|
||||
如果需要验证码会返回图片的 base64 编码
|
||||
根据 lang 参数匹配验证码,需要人工输入
|
||||
:param lang: 返回验证码的语言(en/cn)
|
||||
:return: 验证码的 POST 参数
|
||||
"""
|
||||
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'
|
||||
resp = self.session.get(api)
|
||||
show_captcha = re.search(r'true', resp.text)
|
||||
|
||||
if show_captcha:
|
||||
put_resp = self.session.put(api)
|
||||
json_data = json.loads(put_resp.text)
|
||||
img_base64 = json_data['img_base64'].replace(r'\n', '')
|
||||
with open('./captcha.jpg', 'wb') as f:
|
||||
f.write(base64.b64decode(img_base64))
|
||||
img = Image.open('./captcha.jpg')
|
||||
if lang == 'cn':
|
||||
import matplotlib.pyplot as plt
|
||||
plt.imshow(img)
|
||||
print('点击所有倒立的汉字,在命令行中按回车提交')
|
||||
points = plt.ginput(7)
|
||||
capt = json.dumps({'img_size': [200, 44],
|
||||
'input_points': [[i[0] / 2, i[1] / 2] for i in points]})
|
||||
else:
|
||||
img_thread = threading.Thread(target=img.show, daemon=True)
|
||||
img_thread.start()
|
||||
capt = input('请输入图片里的验证码:')
|
||||
# 这里必须先把参数 POST 验证码接口
|
||||
self.session.post(api, data={'input_text': capt})
|
||||
return capt
|
||||
return ''
|
||||
|
||||
def _get_signature(self, timestamp: int or str):
|
||||
"""
|
||||
通过 Hmac 算法计算返回签名
|
||||
实际是几个固定字符串加时间戳
|
||||
:param timestamp: 时间戳
|
||||
:return: 签名
|
||||
"""
|
||||
ha = hmac.new(b'd1b964811afb40118a12068ff74a12f4', digestmod=hashlib.sha1)
|
||||
grant_type = self.login_data['grant_type']
|
||||
client_id = self.login_data['client_id']
|
||||
source = self.login_data['source']
|
||||
ha.update(bytes((grant_type + client_id + source + str(timestamp)), 'utf-8'))
|
||||
return ha.hexdigest()
|
||||
|
||||
def _check_user_pass(self):
|
||||
"""
|
||||
检查用户名和密码是否已输入,若无则手动输入
|
||||
"""
|
||||
if not self.username:
|
||||
self.username = input('请输入手机号:')
|
||||
if self.username.isdigit() and '+86' not in self.username:
|
||||
self.username = '+86' + self.username
|
||||
|
||||
if not self.password:
|
||||
self.password = input('请输入密码:')
|
||||
|
||||
@staticmethod
|
||||
def _encrypt(form_data: dict):
|
||||
with open('./encrypt.js') as f:
|
||||
js = execjs.compile(f.read())
|
||||
return js.call('Q', urlencode(form_data))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
account = ZhihuAccount('', '')
|
||||
account.login(captcha_lang='en', load_cookies=True)
|
||||
|
||||
Reference in New Issue
Block a user