|
1 | | -import re |
2 | | - |
3 | 1 | from bs4 import BeautifulSoup |
4 | | -from requests import Session |
5 | 2 |
|
| 3 | +from ..AuthSession import AuthSession |
| 4 | +from ..utils.vcode import get_solver |
| 5 | +from ..utils.rsa import rsa_encrypt_by_pkcs1 |
6 | 6 |
|
7 | | -class ZFWSession(Session): |
8 | | - BASE = 'https://zfw.xidian.edu.cn' |
| 7 | +class ZFWSession(AuthSession): |
| 8 | + COOKIE_NAME = 'zfw' |
| 9 | + _BASE = 'zfw.xidian.edu.cn' |
| 10 | + BASE = f'https://{_BASE}' |
9 | 11 |
|
10 | | - def __init__(self, username, password, *args, **kwargs): |
11 | | - super(ZFWSession, self).__init__(*args, **kwargs) |
12 | | - self.headers.update({ |
13 | | - 'User-Agent': 'Mobile' |
14 | | - }) |
15 | | - soup = BeautifulSoup(self.get(self.BASE).text, "lxml") |
16 | | - vcv = soup.find('input', type='hidden').get('value') |
17 | | - error = re.findall( |
18 | | - r'请修复以下错误<\/p><ul><li>(.*?)<', |
19 | | - self.post(self.BASE + '/login', data={ |
20 | | - "LoginForm[username]": username, |
21 | | - "LoginForm[password]": password, |
22 | | - "_csrf": vcv, |
23 | | - "login-button": "" |
24 | | - }).text |
| 12 | + def __init__(self, username, password): |
| 13 | + super().__init__( |
| 14 | + f'{self.COOKIE_NAME}_{username}', headers={'User-Agent': 'Mobile'} |
| 15 | + ) |
| 16 | + if self.is_logged_in(): |
| 17 | + return |
| 18 | + else: |
| 19 | + self.cookies.clear() |
| 20 | + form = BeautifulSoup( |
| 21 | + self.get(self.BASE).text, 'lxml' |
| 22 | + ).findChild(attrs={'id': 'login-form'}) |
| 23 | + headers = { |
| 24 | + **self.headers, |
| 25 | + 'X-Requested-With': 'XMLHttpRequest', |
| 26 | + 'X-CSRF-Token': form.find('input', attrs={'name': '_csrf-8800'}).get('value') |
| 27 | + } |
| 28 | + enc_password = rsa_encrypt_by_pkcs1( |
| 29 | + form.find('input', id='public').get('value'), password |
25 | 30 | ) |
26 | | - self.headers.pop('User-Agent') |
27 | | - if len(error) > 0: |
28 | | - raise ConnectionError(error[0]) |
| 31 | + data = { |
| 32 | + 'LoginForm[username]': username, |
| 33 | + 'LoginForm[password]': enc_password |
| 34 | + } |
| 35 | + for _ in range(5): |
| 36 | + data['LoginForm[verifyCode]'] = get_solver(self._BASE)(self.get( |
| 37 | + f'{self.BASE}/site/captcha' |
| 38 | + ).content) |
| 39 | + res = self.post( |
| 40 | + f'{self.BASE}/site/validate-user', headers=headers, data=data |
| 41 | + ) |
| 42 | + if res.status_code == 200 or res.json()['success']: |
| 43 | + break |
| 44 | + else: |
| 45 | + raise ConnectionError('登录失败') |
| 46 | + res = self.post(self.BASE, headers=headers, data=data) |
| 47 | + if res.status_code != 302 and res.headers.get( |
| 48 | + 'X-Redirect' |
| 49 | + ) != 'http://zfw.xidian.edu.cn/home': |
| 50 | + raise ConnectionError('登录失败') |
| 51 | + |
| 52 | + def is_logged_in(self): |
| 53 | + return self.get( |
| 54 | + f'{self.BASE}/login', allow_redirects=False |
| 55 | + ).status_code == 302 |
0 commit comments