Skip to content

Commit 654ff75

Browse files
authoredMar 20, 2024
Update haiku.py
1 parent c6d0f17 commit 654ff75

File tree

1 file changed

+110
-75
lines changed

1 file changed

+110
-75
lines changed
 

‎haiku.py

+110-75
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,124 @@
1-
import requests
1+
import json
22
import os
3+
import requests
34
import datetime
45
import time
6+
import random
7+
import base64
8+
import cv2
9+
import pytesseract
10+
import tkinter as tk
11+
from tkinter import simpledialog
12+
13+
def login():
14+
# 获取验证码
15+
response = requests.get("https://buct.smartclass.cn/Login.aspx", headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"})
16+
cookies = response.cookies.get_dict()
17+
verifycode_json = json.loads(response.text)
18+
19+
# 显示验证码图片
20+
verifyimg = base64.b64decode(verifycode_json["Value"]["img"])
21+
with open("verifyimg.png", "wb") as f:
22+
f.write(verifyimg)
23+
image = cv2.imread("verifyimg.png")
24+
cv2.imshow("Verification Code", image)
25+
cv2.waitKey(0)
26+
cv2.destroyAllWindows()
27+
28+
# 输入验证码
29+
verifycode = pytesseract.image_to_string(image).strip()
30+
if not verifycode:
31+
verifycode = simpledialog.askstring("Input Code", "Please enter the verification code:")
532

6-
# Login
7-
url = "https://buct.smartclass.cn/Login.aspx"
8-
response = requests.get(url, headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"})
9-
resp_cookies = response.cookies
33+
# 登录
34+
login_data = {
35+
"UserName": "",
36+
"PassWord": "",
37+
"isRember": "false",
38+
"VerifyCode": verifycode,
39+
"VerifyCodeId": verifycode_json["Value"]["Code"],
40+
"redirectUri": ""
41+
}
42+
response = requests.post("https://buct.smartclass.cn/Home/Login", data=login_data, headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"}, cookies=cookies)
43+
cookies.update(response.cookies.get_dict())
44+
return cookies
1045

11-
# Get verification code
12-
random_num = int(str(int(time.time() * 1000000000)) * 0.0000001)
13-
verify_code_url = f"https://buct.smartclass.cn/home/VerifyImage2?{random_num}"
14-
response = requests.get(verify_code_url, cookies=resp_cookies, headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"})
15-
verify_code_json = response.text
16-
verify_code_img = response.content.decode("base64")
17-
verify_code = input("Input verification code: ")
46+
def get_csrf_token(cookies):
47+
# 获取 CSRF 令牌
48+
response = requests.get("https://buct.smartclass.cn/wechat.json?r=2021-01-29", headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"}, cookies=cookies)
49+
csrkKey = json.loads(response.text)["csrkKey"]
50+
token = "".join(csrkKey[int((time.time() - time.time() % (10 ** i)) / (10 ** i))] for i in range(10, 0, -1))
51+
return token
1852

19-
# Login
20-
login_url = "https://buct.smartclass.cn/Home/Login"
21-
login_data = {
22-
"UserName": "",
23-
"PassWord": "",
24-
"isRember": "false",
25-
"VerifyCode": verify_code,
26-
"VerifyCodeId": verify_code_json["Code"],
27-
"redirectUri": ""
28-
}
29-
response = requests.post(login_url, data=login_data, cookies=resp_cookies, headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"})
30-
login_return = response.text
53+
def download_videos(cookies, token):
54+
# 获取课程列表
55+
today = datetime.datetime.now().strftime("%Y-%m-%d")
56+
fromday = (datetime.datetime.now() - datetime.timedelta(days=36)).strftime("%Y-%m-%d")
57+
response = requests.get(f"https://buct.smartclass.cn/Webapi/V1/Video/GetMyVideoList?csrkToken={token}&TeacherName=&Sort=StartTime&TagID=&SyCommonKey=&StartDate={fromday}&EndDate={today}&Order=1&PageSize=100&PageNumber=1&attribute=&IncludePublic=", headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"}, cookies=cookies)
58+
video_data = json.loads(response.text)
3159

32-
# Get CSRF token
33-
wechat_url = "https://buct.smartclass.cn/wechat.json?r=2021-01-29"
34-
response = requests.get(wechat_url, headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"})
35-
wechat_json = response.text
36-
csrf_key = wechat_json["csrkKey"]
37-
token = "".join([csrf_key[int((time.time() - time.time() % i) / i)] for i in [1000000000000, 100000000000, 10000000000, 1000000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10]])
60+
# 下载视频
61+
total_count = video_data["TotalCount"]
62+
for i in range(total_count):
63+
cover = video_data["Data"][i]["Cover"]
64+
start_time = video_data["Data"][i]["StartTime"]
65+
course_name = video_data["Data"][i]["CourseName"]
66+
start_time_formatted = start_time.replace(":", "_")
3867

39-
# Get video list
40-
today = (datetime.datetime.now() - datetime.timedelta(days=36)).strftime("%Y-%m-%d")
41-
from_day = (datetime.datetime.now() - datetime.timedelta(days=14)).strftime("%Y-%m-%d")
42-
video_list_url = f"https://buct.smartclass.cn/Webapi/V1/Video/GetMyVideoList?csrkToken={token}&TeacherName=&Sort=StartTime&TagID=&SyCommonKey=&StartDate={from_day}&EndDate={today}&Order=1&PageSize=100&PageNumber=1&attribute=&IncludePublic="
43-
response = requests.get(video_list_url, cookies=resp_cookies, headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"})
44-
video_list = response.text
45-
covers = [item.split("?")[0] for item in response.json()["Data"]["Cover"]]
46-
start_times = response.json()["Data"]["StartTime"]
47-
total_count = response.json()["TotalCount"]
48-
course_names = response.json()["Data"]["CourseName"]
68+
# 下载 VGA 视频
69+
vga_url = cover.replace("/1/", "/0/").replace("000.jpg", "VGA.mp4")
70+
if not os.path.exists(f"D:\\OvlerDrive\\OneDrive\\downloads\\{course_name}\\{start_time_formatted}_VGA.mp4"):
71+
response = requests.get(vga_url, headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36"}, cookies=cookies)
72+
with open(f"D:\\OvlerDrive\\OneDrive\\downloads\\{course_name}\\{start_time_formatted}_VGA.mp4", "wb") as f:
73+
f.write(response.content)
4974

50-
# Process video list
51-
output_vga = ["#EXTM3U"]
52-
output_video1 = ["#EXTM3U"]
53-
for i in range(total_count):
54-
cover = covers[i]
55-
start_time = start_times[i].replace(":", "_")
56-
course_name = course_names[i]
75+
# 下载 Video1 视频
76+
video1_url = cover.replace("/1/", "/0/").replace("000.jpg", "Video1.mp4")
77+
if not os.path.exists(f"D:\\OvlerDrive\\OneDrive\\downloads\\{course_name}\\Video1\\{start_time_formatted}_Video1.mp4"):
78+
response = requests.get(video1_url, headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36"}, cookies=cookies)
79+
if not os.path.exists(f"D:\\OvlerDrive\\OneDrive\\downloads\\{course_name}\\Video1"):
80+
os.makedirs(f"D:\\OvlerDrive\\OneDrive\\downloads\\{course_name}\\Video1")
81+
with open(f"D:\\OvlerDrive\\OneDrive\\downloads\\{course_name}\\Video1\\{start_time_formatted}_Video1.mp4", "wb") as f:
82+
f.write(response.content)
83+
time.sleep(0.1)
5784

58-
vga_path = f"D:\\OvlerDrive\\OneDrive\\downloads\\{course_name}\\{start_time}_VGA.mp4"
59-
if not os.path.exists(vga_path):
60-
response = requests.post("http://localhost:16800/jsonrpc", json={
61-
"jsonrpc": "2.0",
62-
"method": "aria2.addUri",
63-
"id": "QXJpYU5nXzE2NDY4MzM4NDJfMC4zNDc3MTcxOTgzNTA1NDQ1",
64-
"params": [[cover.replace("000.jpg", "VGA.mp4")], {"out": f"{course_name}/{start_time}_VGA.mp4"}]
65-
})
85+
def get_live_streams(cookies, token):
86+
# 获取直播列表
87+
today = datetime.datetime.now().strftime("%Y-%m-%d")
88+
fromday = (datetime.datetime.now() + datetime.timedelta(days=7)).strftime("%Y-%m-%d")
89+
response = requests.get(f"https://buct.smartclass.cn/Webapi/V1/Live/GetMyLiveList?csrkToken={token}&MajorUserID=&ClassroomID=&Sort=IsLiving%20desc%2CIsCompleted%2CStartTime&StartDate={today}&EndDate={fromday}&PageSize=50&PageNumber=1&attribute=&IncludePublic=true", headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"}, cookies=cookies)
90+
live_data = json.loads(response.text)
6691

67-
video1_path = f"D:\\OvlerDrive\\OneDrive\\downloads\\{course_name}\\Video1\\{start_time}_Video1.mp4"
68-
if not os.path.exists(video1_path):
69-
response = requests.post("http://localhost:16800/jsonrpc", json={
70-
"jsonrpc": "2.0",
71-
"method": "aria2.addUri",
72-
"id": "QXJpYU5nXzE2NDY4MzM4NDJfMC4zNDc3MTcxOTgzNTA1NDQ1",
73-
"params": [[cover.replace("000.jpg", "Video1.mp4")], {"out": f"{course_name}/Video1/{start_time}_Video1.mp4"}]
74-
})
92+
# 获取直播流信息
93+
total_count = live_data["TotalCount"]
94+
page2read = int(total_count * 0.02 + 1)
95+
vga_output = ["#EXTM3U"]
96+
for page in range(1, page2read + 1):
97+
response = requests.get(f"https://buct.smartclass.cn/Webapi/V1/Live/GetMyLiveList?csrkToken={token}&MajorUserID=&ClassroomID=&Sort=IsLiving%20desc%2CIsCompleted%2CStartTime&StartDate={today}&EndDate={fromday}&PageSize=50&PageNumber={page}&attribute=&IncludePublic=true", headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"}, cookies=cookies)
98+
live_data = json.loads(response.text)
99+
for i in range(live_data["TotalCount"]):
100+
schedule_id = live_data["Data"][i]["ScheduleID"]
101+
title = live_data["Data"][i]["Title"]
102+
response = requests.post("https://buct.smartclass.cn/Live/GetLiveStreamInfo", data={"ScheduleId": schedule_id}, headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36"}, cookies=cookies)
103+
stream_data = json.loads(response.text)
104+
vga = stream_data["Value"]["LanLiveMainRtmpSourceStreamNames"][0]
105+
video1 = stream_data["Value"]["LanLiveMainRtmpSourceStreamNames"][1]
106+
if vga and vga not in vga_output:
107+
vga_output.append(f"#EXTINF:-1,{title}_vga")
108+
vga_output.append(vga)
109+
if video1 and video1 not in vga_output:
110+
vga_output.append(f"#EXTINF:-1,{title}_video1")
111+
vga_output.append(video1)
112+
time.sleep(0.1)
75113

76-
if cover.replace("000.jpg", "VGA.mp4") not in output_vga:
77-
output_vga.append(f"#EXTINF:-1,{course_name}_vga")
78-
output_vga.append(cover.replace("000.jpg", "VGA.mp4"))
79-
if cover.replace("000.jpg", "Video1.mp4") not in output_video1:
80-
output_video1.append(f"#EXTINF:-1,{course_name}_video1")
81-
output_video1.append(cover.replace("000.jpg", "Video1.mp4"))
82-
time.sleep(0.1)
114+
with open("vga.m3u", "w", encoding="utf-8") as f:
115+
f.write("\n".join(vga_output))
83116

84-
# Save playlists
85-
with open("E:\\Video\\smartclass\\vga.m3u", "w", encoding="utf-8") as f:
86-
f.write("\n".join(output_vga))
117+
def main():
118+
cookies = login()
119+
token = get_csrf_token(cookies)
120+
download_videos(cookies, token)
121+
get_live_streams(cookies, token)
87122

88-
with open("E:\\Video\\smartclass\\video1.m3u", "w", encoding="utf-8") as f:
89-
f.write("\n".join(output_video1))
123+
if __name__ == "__main__":
124+
main()

0 commit comments

Comments
 (0)
Please sign in to comment.