Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

精简代码,更换配置方式为 JSON #42

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .gitattributes

This file was deleted.

11 changes: 0 additions & 11 deletions .github/dependabot.yml

This file was deleted.

61 changes: 0 additions & 61 deletions .github/workflows/main.yml

This file was deleted.

37 changes: 0 additions & 37 deletions .github/workflows/main_npd.yml

This file was deleted.

3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/.idea/
/__pycache__/
local_only.py
local_only.py
account.json
10 changes: 10 additions & 0 deletions account.json.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"username": "15322492759",
"password": "blablabla"
},
{
"username": "19528495602",
"password": "password2"
}
]
86 changes: 27 additions & 59 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,73 +1,41 @@
import os
import time
import sys
import json
from study import study

# cur dir to main.py file dir
os.chdir(os.path.dirname(os.path.abspath(__file__)))

def getAccounts():
result = []

usernameRaw = os.getenv("USERNAME", "")
if len(usernameRaw.split('\n')) == 1:
# Single User
passwd = os.environ["PASSWORD"]
if usernameRaw and passwd:
result.append((usernameRaw, passwd))
else:
# Multiple Users
account_lines = usernameRaw.split('\n')
for lineN, line in enumerate(account_lines):
lineSplit = line.split(' ')
if len(lineSplit) == 3:
lineSplit = lineSplit[:2]
print('现在可以删除组织ID了')
elif len(lineSplit) != 2:
raise Exception(f"第{lineN}行账号格式错误")
result.append(lineSplit)

if not result:
raise Exception("没有被配置的账号!请设置Secret: USERNAME(和PASSWORD)")
return result


ua = os.getenv('UA',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36 Edg/106.0.1370.42')


# Windows Automated Task Management
task_name="Daxuexi_18S4F65D"
# install windows automated task
task_name = "Daxuexi_18S4F65D"
if os.name == 'nt':
if task_name in os.popen("SCHTASKS /query").read():
print("脚本配置的计划任务已存在")
# + 检测路径
else:
if 1: # change to 0 if you want to manage it yourself
input("没有脚本配置的计划任务,按任意键创建;或者退出并把main.py 43行的1改成0")
k=os.popen(f"{sys.executable} ./runtest.py").read()
if 'SHOULDBEFINE\n'!=k:
if 'FAILIMPORT\n'==k:
print("依赖问题")
else:
print('创建失败?Python位置不对?')
exit(1)
create=os.popen(f'''SchTasks /Create /SC DAILY /MO 2 /TN {task_name} /TR "'{sys.executable}' '{os.path.realpath(__file__)}'" /ST 09:00''')
print('创建成功')
k = os.popen(f"{sys.executable} ./runtest.py").read()
if 'SHOULDBEFINE\n' != k:
if 'FAILIMPORT\n' == k:
raise ImportError("检查依赖安装 pip install -r requirements.txt")
else:
raise ValueError(k)
create = os.popen(
f'''SchTasks /Create /SC DAILY /MO 2 /TN {task_name} /TR "'{sys.executable}' '{os.path.realpath(__file__)}'" /ST 09:00''')
print('创建成功: ', create)

# read account data and check they all satisfy 'username', 'password' pattern
if not os.path.exists('account.json'):
raise FileNotFoundError("检查 account.json 是否存在")
with open('account.json', 'r', encoding='utf-8') as f:
accounts = json.load(f)

if type(accounts) != list or not all('username' in account and 'password' in account for account in accounts):
raise ValueError('检查 accounts.json 数据格式')

# accounts = getAccounts()
accounts=[('********', '*********')]
print(f'账号数量:{len(accounts)}')
successful = 0
count = 0
for username, password in accounts:
if username=='********':
continue
count += 1
print(f'--User {count}--')
if study(username, password, ua):
for i, account in enumerate(accounts):
print(f'User {i+1}')
if study(account['username'], account['password']):
successful += 1

failed = count - successful
print('--Summary--')
print(f'成功:{successful},失败:{failed}')
if failed != 0:
raise Exception(f'有{failed}个失败!')
print(f'成功:{successful},失败:{len(accounts) - successful}')
87 changes: 25 additions & 62 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,78 +1,41 @@
# 北京青年大学习

~~基于GitHub Action运行,简洁版本~~

GitHub IP被封啦,只能本地运行了

在运行时获取最新一集,如未学习进行学习,已学习则结束

建议配置运行频率一周2次(默认为3天一次),没有成功会出错,默认配置下GitHub会向邮箱推送,所以没有推送功能

一些特性:多账号支持,已学习则跳过,自动获取组织ID,验证码识别

# 本地运行 -Windows
下载[Python](https://www.python.org/downloads/),已知3.7-3.9都可以,3.11某些依赖的库不支持。

下载这个repo并解压。

安装依赖: 在解压出来的目录里运行`pip install -r requirements.txt`或`pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple` (如果国内环境+没配置代理)

配置账号: main.py 中 accounts = getAccounts() 一行改成 accounts=[('账号1', '密码1'),('账号2', '密码2'),('账号3', '密码3')]形式

运行: 运行`main.py`

自动运行:可搜索“计划任务”相关,Windows下脚本会自动尝试配置2天一次的计划任务

# 本地运行 -Linux


```sh
# 首次运行建立环境
git clone https://github.com/startkkkkkk/Beijing_Daxuexi_Simple.git
cd Beijing_Daxuexi_Simple
pip install -r requirements.txt
```

然后新建 `run.sh`,写入

```
#!/usr/bin/bash
export USERNAME=你的用户名
export PASSWORD=你的密码
python main.py
```

添加执行权限 `chmod +x run.sh`,之后使用 crontab 配置自动运行,执行 `crontab -e`,在打开的编辑器中写入

```
0 8 */3 * * /home/username/Beijing_Daxuexi_Simple/run.sh
```
## 特性

注意修改以上路径到你自己的路径。
- 多账号支持
- 已学习则跳过
- 自动获取组织ID
- 验证码识别
- 本地定时运行

然后重启 cron (`sudo service cron restart`) 即可。
## 运行环境

# How to use
- Python 3.7 +
- 运行 `pip install -r requirements.txt`

1. Fork (+ Star)
2. 填写以下SECRET (名称均为大写)
> Mac ARM 系列的同学需要使用 [miniforge](https://github.com/conda-forge/miniforge) 安装,运行 `conda install --file requirements.txt` 即可。

​ (账号密码为登录青春北京的信息,可以在[这里](https://m.bjyouth.net/site/login)测试登录信息,[如何添加SECRET](https://docs.github.com/cn/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository))
## 本地运行

​ 方法1:单用户
### 1. 填写 account.json

| Name | Description |
| -------- | :----------------------------------------: |
| USERNAME | 账号(必须) |
| PASSWORD | 密码(必须) |
将 `account.json.example` 复制一份并重命名为 `account.json` 后,按照格式填写若干个用户名、密码。

​ 方法2:支持多用户
> 注意 json 文件的格式,在每个大括号内部的*结尾*不能有多余的逗号:
>
> ![CleanShot 2022-11-17 at 17.10.08@2x](https://tva1.sinaimg.cn/large/008vxvgGly1h888phmxd8j30ca05iwek.jpg)

| Name | Description |
| -------- | ---------------------------------------------------------- |
| USERNAME | 账号信息(必须): 每一行为 ***账号 密码*** 中间由空格隔开(由于需要手动权限更新workflow只能复用USERNAME这个名字了) |
### 2. 运行脚本

3. 在Actions界面**手动启用(默认被禁用)** Workflows,**DaXueXi** 自动跟随本分支更新(以希望在有变化时不用再手动fetch upstream),如有安全顾虑**或需要修改**等可选择没有自动更新的 **DaXueXi (No update)**
4. (可以手动运行一次试验),可以在Run python中看到打印的结果信息
使用 `python main.py` 命令运行脚本即可。Windows 环境下会自行安装定时任务。

## 定时运行(Linux)

1. 使用 crontab 配置自动运行,执行 `crontab -e`。
2. 在打开的编辑器中写入
```
0 8 */3 * * /你的文件夹绝对路径/run.sh
```
3. 退出文件编辑并保存即可。
4 changes: 4 additions & 0 deletions run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

cd "$(dirname "$0")"
python3 main.py
14 changes: 4 additions & 10 deletions study.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,22 @@
import re
import time
import traceback

import requests

from utility import encrypt, cap_recognize

UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36 Edg/106.0.1370.42'


def study(username, password, ua):
def study(username, password):
# return 1:success;0:fail
url = ''
tryTime = 0
while tryTime < 4:
try:
bjySession = requests.session()
bjySession.timeout = 5 # set session timeout
bjySession.headers.update({"User-Agent": ua, })
bjySession.headers.update({"User-Agent": UA, })
touch = bjySession.get(url="https://m.bjyouth.net/site/login")
capUrl = "https://m.bjyouth.net" + re.findall(
r'src="(/site/captcha.+)" alt=', touch.text)[0]
Expand Down Expand Up @@ -81,13 +82,6 @@ def study(username, password, ua):
print(f'{title} 在运行前已完成,退出')
return 1

# pattern = re.compile(r'https://h5.cyol.com/special/daxuexi/(\w+)/m.html\?t=1&z=201')
# result = pattern.search(url)
# if not result:
# print(f'Url pattern not matched: {url}')
# return 0
#
# end_img_url = f'https://h5.cyol.com/special/daxuexi/{result.group(1)}/images/end.jpg'
study_url = f"https://m.bjyouth.net/dxx/check"
r = bjySession.post(study_url, json={"id": str(courseId), "org_id": int(nOrgID)}) # payload

Expand Down