Skip to content
This repository has been archived by the owner on Oct 6, 2023. It is now read-only.

Commit

Permalink
Merge pull request #80 from 838239178/develop
Browse files Browse the repository at this point in the history
[Bug,Feat] 修复登录异常,添加验证码识别
  • Loading branch information
ShiJh⭐ authored Jun 17, 2022
2 parents 74db8e7 + c4fd40a commit 1b7b914
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 21 deletions.
42 changes: 31 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,25 @@

[此处展示最近更新日志,完整日志搓这里](./doc/Log.md)

> 2022.03.26: 感谢 @miscdec 对开源库的贡献,现在添加了push_plus推送渠道,并修复了一些异常。
>
> 2022.03.27: 代理池极不稳定
>
> 2022.03.30: 感谢 @Dark-Existed 贡献了Docker部署脚本,请使用环境变量配置相关参数
>
> 2022.05.11: 不使用代理IP的场景可使用Python3.7版本
>
> 2022.06.03:针对未知打卡失败的情况添加重试措施
>
> 2022.06.17:⚠ **重要:验证码检测回归**,现在需要验证码识别技术,请使用`1.3.0`及以上版本。⚠
🤺妈妈再也不用担心我团课没看被团支书赶着催了

### 点个:star:再走吧,❤感谢大家的Star和Fork,有问题可以发issue

**仅供福建共青团团员学习交流使用**

~~浙江团员可以点击这里[青春浙江](https://gist.github.com/838239178/ddad90e8c5e52f5fa8f0febea6109f24)~~
**仅供福建共青团团员学习交流使用** 项目遵循GPL协议,请勿拿来盈利、诈骗和违法之事!否则后果需要自负。

### 参与贡献!

:pen: 如果你有新的或更好消息推送方式 请参考 [消息推送贡献文档](./doc/send_module_rule.md) 做出你的贡献!
🖊️ 如果你有新的或更好OCR识别方式 请参考 [OCR贡献文档](https://github.com/838239178/tk-auto-study/blob/1.2.5/doc/OCR_Module_Rule.md) 做出你的贡献!

🖊️ 如果你有新的或更好消息推送方式 请参考 [消息推送贡献文档](https://github.com/838239178/tk-auto-study/blob/1.2.5/doc/send_module_rule.md) 做出你的贡献!

## 使用方法

Expand All @@ -34,6 +32,16 @@
A7E74D2B6282AEB1C5EA3C28D25660A7
```

#### 申请Ocr识别接口的权限

[详细教程请点击这里](https://blog.pressed.top/2021/02/14/signUpBaiduOcr/)

*请选择使用一种可以识别文字的api,建议使用BaiduAI的Ocr接口*

- 首先要有一个百度账号,进入[这个网址](https://ai.baidu.com/),点击控制台并登录
- 完成个人实名认证,申请文字识别的使用权
- 点击管理应用,点击创建应用,按要求填一些信息,创建完成后记住**API KEY****SECRET KEY**

#### 部署在平台上定时执行

这里介绍如何在GitHubActions中运行,因代理IP的相关代码,需确保**Python3.9**及以上版本。
Expand All @@ -42,8 +50,10 @@ A7E74D2B6282AEB1C5EA3C28D25660A7

- 添加三个secrets,分别为:username, pwd, pub_key

- `1.3.0`开始,需要添加验证码识别的OCR的 api_key,secret_key,ocr_type

-[该文件](./.github/workflows/run.yml)中的`#`删除并修改cron为你想要触发的时间,默认是每周三14点运行一次,cron如何写请自行百度

![image](https://user-images.githubusercontent.com/55338151/161259594-21812419-25e3-4b1f-b64f-e06b826351b8.png)

- 进入 Actions 中手动触发一次(点击auto-study 右边 Run workflow),测试是否成功
Expand Down Expand Up @@ -79,7 +89,7 @@ crontab -e
# 将下面这行复制到里面,cd的路径按照需要更改
00 08 * * 3 cd /root/tk-auto-study && python3 main.py >> crontab.log 2>&1
# 或者
00 08 * * python3 /root/tk-auto-study/main.py >> crontab.log 2>&1
00 08 * * 3 python3 /root/tk-auto-study/main.py >> crontab.log 2>&1
```

使用 `crontab -l` 查看是否修改成功
Expand All @@ -92,6 +102,16 @@ crontab -e
docker-compose up -d
```

## 可选识别类型

> `1.3.0`
GithubAction(可选)添加新的secrets OCR_TYPE 来指定识别类型

其他方式在config.json中修改指定配置项即可

- baidu_image [默认方法,需要到百度AI中申请](https://blog.pressed.top/2021/02/14/signUpBaiduOcr/)

## 可选消息推送

> `1.2.2` 版本及以上可用
Expand Down Expand Up @@ -139,5 +159,5 @@ GithubAction用户可通过添加secrets:send_type, send_key, send_mode 来使

## 赏我一杯Coffee

![qq_pic_merged_1633171137809](https://cdn.jsdelivr.net/gh/838239178/PicgoBed/img/68747470733a2f2f63646e2e6a7364656c6976722e6e65742f67682f3833383233393137382f506963676f4265642f696d672f313633333137313136342e6a7067.jpg)![qq_pic_merged_1633171137809](https://cdn.jsdelivr.net/gh/838239178/PicgoBed/img/qq_pic_merged_1633171137809.jpg)
![qq_pic_merged_1633171137809](https://cdn.jsdelivr.net/gh/838239178/PicgoBed/img/qq_pic_merged_1633171137809.jpg)

5 changes: 5 additions & 0 deletions config.json.bak
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
"key": "填写server酱或其他的SendKey",
"mode": "默认fail(fail/success/both)"
},
"ocr": {
"sk": "填写API KEY",
"ak": "填写SECRET KEY",
"type": "baidu_image"
},
"extUsers": [
{
"username": "",
Expand Down
4 changes: 0 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,4 @@ services:
# success, fail, both
- sendMode=
- extUsers=
<<<<<<< HEAD
- TZ=Asia/Shanghai
=======
- TZ=Asia/Shanghai
>>>>>>> 5b038aa82f3f89ea1b4a519c036d35da2d12881c
28 changes: 22 additions & 6 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import urllib3

from exception import KnownException, SendInitException
from ocr_module import util as ocrutil

# 处理https警告
urllib3.disable_warnings()
Expand Down Expand Up @@ -90,10 +91,11 @@ def post_study_record():
error_raise(f"学习失败,{errmsg}")


def post_login(username: str, pwd: str, pub_key):
def post_login(username: str, pwd: str, pub_key: str, code: str):
post_dict = {
'userName': encryptor.encrypt(username, pub_key),
'pwd': encryptor.encrypt(pwd, pub_key)
'pwd': encryptor.encrypt(pwd, pub_key),
'validateCode': encryptor.encrypt(code, pub_key)
}

resp = sess.post(url="https://m.fjcyl.com/mobileNologin",
Expand All @@ -115,14 +117,18 @@ def get_profile_from_config():
pwd = config_json.get('pwd')
pub_key = config_json.get('rsaKey').get('public')

api_key = config_json.get('ocr').get('ak')
secret_key = config_json.get('ocr').get('sk')
ocr_type = config_json.get('ocr').get('type')

send_config = config_json.get('send')
accounts = config_json.get("extUsers")
if send_config is not None:
send_type = send_config.get('type')
send_key = send_config.get('key')
send_mode = send_config.get('mode')
return username, pwd, pub_key, \
send_type, send_key, send_mode, accounts
send_type, send_key, send_mode, accounts, api_key, secret_key, ocr_type


def get_profile_from_env():
Expand All @@ -134,6 +140,11 @@ def get_profile_from_env():
send_mode = os.environ['sendMode']
ext_users = os.environ['extUsers']
accounts = []

api_key = os.environ['ocrKey']
secret_key = os.environ['ocrSecret']
ocr_type = os.environ['ocrType']

if ext_users is not None and ext_users.__len__() > 1:
for userLine in ext_users.split('\n'):
usr_split = userLine.split(" ")
Expand All @@ -147,16 +158,17 @@ def get_profile_from_env():
account['pwd'] = usr_split[1]
accounts.append(account)
return username, pwd, pub_key, \
send_type, send_key, send_mode, accounts
send_type, send_key, send_mode, accounts, api_key, secret_key, ocr_type


def login(username, pwd, pub_key):
has_try = 0
logging.info(f"正在登录尾号{username[-4:]}")
code = ocrutil.get_validate_code(sess)
while has_try < MAX_TRY:
# do login
try:
post_login(username, pwd, pub_key)
post_login(username, pwd, pub_key, code)
break
except ConnectionError as e:
logging.error(f'尾号{username[-4:]}登录失败,原因:{e}')
Expand Down Expand Up @@ -237,9 +249,13 @@ def run(use_config: bool, use_proxy: bool = False):
# get default config
username, pwd, pub_key, \
send_type, send_key, send_mode, \
accounts = get_profile_from_config() if use_config else get_profile_from_env()
accounts, \
api_key, secret_key, ocr_type = get_profile_from_config(
) if use_config else get_profile_from_env()
# init sender
init_sender(send_type, send_key, send_mode)
# init ocr
ocrutil.init_ocr(ocr_type, api_key, secret_key)
# init proxy
if use_proxy:
init_proxy()
Expand Down
6 changes: 6 additions & 0 deletions ocr_module/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from . import util


__all__ = [
"util"
]
43 changes: 43 additions & 0 deletions ocr_module/util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from datetime import datetime
import importlib
import logging
import base64
import time

from exception.exceptions import KnownException

ocr_util = None

def init_ocr(ocr_type: str, ak: str, sk: str):
global ocr_util
if ocr_type is None or ocr_type == '':
ocr_type = "baidu_image"
try:
ocr_util = importlib.import_module(
f"ocr_module.{ocr_type}.{ocr_type}_ocr")
except ModuleNotFoundError:
raise KnownException("ocr类型不存在,请更换类型")

if ocr_util.is_need_keys():
ocr_util.set_keys(ak, sk)
logging.info(f"使用 OCR {ocr_type}")

def get_validate_code(sess) -> str:
max_try = 5
has_try = 0
while has_try < max_try:
resp = sess.get(
url=f"https://m.fjcyl.com/validateCode?0.{datetime.microsecond}&width=58&height=19&num=4")
try:
# noinspection PyUnresolvedReferences
res = ocr_util.get_result(base64.b64encode(resp.content))
logging.info('获取验证码成功')
return res
except Exception as e:
logging.warning(f'获取验证码失败,原因:{e}')
logging.warning(f'正在重试, 次数:{has_try}')
has_try += 1
time.sleep(1)

if has_try == max_try:
raise KnownException("验证码解析失败,请尝试更换方式或发issue寻求帮助")

0 comments on commit 1b7b914

Please sign in to comment.