这是一个 2.0 版的 Fuck信仰不息🗽

This is the 2.0 version of Fuck Xin Yang Bu Xi 🗽

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
from selenium.webdriver.chrome.service import Service
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup
from email.mime.text import MIMEText
from email.header import Header
from smtplib import SMTP_SSL
import random
import json
import requests
import os
import time
import cv2
import numpy as np


def send_email(msg, receiver):
host_server = '' # 邮箱smtp服务器
user = '' # user 为发件人的邮箱号码
pwd = '' #pwd 为邮箱的授权码
sender_mail = '' #发件人的邮箱
#邮件的正文内容
mail_content = msg

#添加机器人签名
mail_sign = \
'''
\n
---

No need to reply!
Contact me: wgx@dijk.eu.org
'''

#邮件标题
mail_title = '【打卡消息推送】'
#ssl登录
smtp = SMTP_SSL(host_server)
#set_debuglevel()是用来调试的。参数值为1表示开启调试模式,参数值为0关闭调试模式
smtp.set_debuglevel(0)
smtp.ehlo(host_server)
smtp.login(user, pwd)

msg = MIMEText(mail_content + mail_sign, "plain", 'utf-8')
msg["Subject"] = Header(mail_title, 'utf-8')
msg["From"] = sender_mail
msg["To"] = receiver
smtp.sendmail(sender_mail, receiver, msg.as_string())
smtp.quit()

def bin_img(img):
# 设定纯白色的阈值为255(注意:OpenCV使用BGR而不是RGB)
white_threshold = 246
# 通过比较找出不是纯白色的像素位置
not_white = np.any(img < white_threshold, axis=-1)
# 创建一个全黑色的图像
black_image = np.zeros_like(img)
# 将非纯白色的像素设为黑色,而其他的保持不变(可选,如果您想只保留纯白色的像素)
img[not_white] = [0, 0, 0]
return img

def download_image(url, filename):
response = requests.get(url)
if response.status_code == 200:
with open(filename, 'wb') as file:
file.write(response.content)

def match_img(big_image, small_image):
# 二值图像
big_image = bin_img(big_image)
small_image = bin_img(small_image)

# 使用模板匹配方法寻找小图在大图中的位置
result = cv2.matchTemplate(big_image, small_image, cv2.TM_CCOEFF_NORMED)

# 获取匹配结果中的最大值和它的位置
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)

# 滑块的顶部左侧点
top_left = max_loc

# 由于我们知道小图的大小,我们可以计算出匹配区域的右下角位置
# bottom_right = (top_left[0] + small_image.shape[1], top_left[1] + small_image.shape[0])

# # 在大图上绘制匹配到的区域
# cv2.rectangle(big_image, top_left, bottom_right, color=(0, 255, 0), thickness=2)

# 显示结果
# cv2.imshow('Match', big_image)
# cv2.waitKey(0)
# cv2.destroyAllWindows()

xcenter_x = top_left[0] + small_image.shape[1] / 2
image_width = big_image.shape[1] # image.shape[1] 给出图像宽度

# 计算百分比
percentage = (xcenter_x / image_width)

return percentage

def wait_for_page_load(driver, timeout=10):
try:
# 使用WebDriverWait等待页面加载,通过执行JavaScript返回document.readyState == 'complete'
page_loaded = WebDriverWait(driver, timeout).until(
lambda d: d.execute_script('return document.readyState') == 'complete'
)
except TimeoutException:
print("在给定的时间内,页面未完全加载!")
return False
return True

def verify(percentage, driver):
slider_button = driver.find_element(By.CSS_SELECTOR, ".ui-slider-btn.init")
slider_track = driver.find_element(By.CSS_SELECTOR, ".ui-slider-wrap") # 假定滑道元素类名是 "ui-slider-wrap"
# 获取滑道的长度
track_width = slider_track.size['width']
# 计算需要拖动的像素距离
offset = track_width * percentage
# 初始化ActionChains对象
action_chains = ActionChains(driver)
# 点击并按住滑块按钮
action_chains.click_and_hold(slider_button).perform()
# 这里我们添加一个非常短暂的延时来模拟人非常平滑的拖动滑块
for step in range(int(offset // 10)):
action_chains.move_by_offset(10, 0).perform() # 小步移动
time.sleep(0.05) # 稍微等待,让动作可见
remaining_offset = offset % 10
action_chains.move_by_offset(remaining_offset, 0).perform() # 移动剩余的距离
time.sleep(0.5) # 完成拖动后稍作停顿
action_chains.release().perform() # 释放滑块

def is_passed(driver):
# 找到包含指定文本的元素
text_element = driver.find_element(By.CLASS_NAME, "ui-slider-text")
# 提取并打印文本
slider_text = text_element.text
print(slider_text)
if slider_text[:4] == "验证成功":
return True
else:
return False

def login_recheck(driver):
elements = driver.find_elements(By.XPATH, '/html/body/form/div/div[2]/div[2]/table')
if len(elements) > 0:
return True
else:
return False

def parse_daka(driver):
# 假设html_content是包含上面所示HTML的字符串
html_content = driver.page_source
# 使用BeautifulSoup解析HTML
soup = BeautifulSoup(html_content, 'html.parser')
# 初始化结果列表
result = []
# 找到表格
table = soup.find('table', {'class': 'kq-message-table'})
# 获取表头中的所有th标签,用于列名称
headers = []
for th in table.find('thead').find_all('th'):
# 每个th标签,获取文本并消除空格和换行符
headers.append(' '.join(th.stripped_strings))
# 遍历表格的每一行
for row in table.find('tbody').find_all('tr'):
# 获取行中的所有td标签
cells = row.find_all('td')
# 每一行的数据都以字典形式存在,字典的键来自标题,值来自单元格数据
data = {}
for index, cell in enumerate(cells):
key = headers[index]
# 提取每个单元格的文本作为数据
data[key] = cell.get_text(strip=True)
# 将每行数据添加至结果列表
result.append(data)
# 将结果列表转换为JSON格式
json_data = json.dumps(result, ensure_ascii=False, indent=4)
return json_data

def daka(user,password, receiver):
options = Options()
options.binary_location = '/opt/google/chrome/google-chrome'
options.add_argument('--headless')
options.add_argument("--disable-dev-shm-usage")
options.add_argument("--no-sandbox")
service = Service(executable_path='/daka/chromedriver')
driver = webdriver.Chrome(service=service,options=options)

retry = 0
verify_adjust = [0.03, 0.02, 0.01, -0.01, -0.02, -0.03]
adjust_index = 0
while True:
driver.get('http://kq.neusoft.com')
while not is_passed(driver):
big_image_elem = driver.find_element(By.ID, "bigImage")
small_image_elem = driver.find_element(By.ID, "smallImage")

big_image_url = big_image_elem.get_attribute("src")
small_image_url = small_image_elem.get_attribute("src")

download_image(big_image_url, "big.png")
download_image(small_image_url, "small.png")
time.sleep(5)

big_image = cv2.imread('big.png')
small_image = cv2.imread('small.png')

percent = match_img(big_image, small_image)
print(percent)
verify(percent - verify_adjust[adjust_index], driver)
time.sleep(2)

retry += 1
adjust_index = retry // 10
if adjust_index > 5:
send_email("打卡失败:重试次数过多,放弃重试!",receiver)
return -1

print("通过验证码!")
user_input_element = driver.find_element(By.XPATH, '/html/body/div[1]/form/div[2]/div/div/div[2]/div[2]/input')
user_input_element.send_keys(user)

pass_input_element = driver.find_element(By.XPATH, "/html/body/div[1]/form/div[2]/div/div/div[2]/div[3]/input")
pass_input_element.send_keys(password)

login_button = driver.find_element(By.XPATH, '/html/body/div[1]/form/div[2]/div/div/div[2]/div[6]/input')
login_button.click()
time.sleep(1)
if login_recheck(driver):
print("登陆成功!")
break

time.sleep(2)
msg = parse_daka(driver)
button = driver.find_element(By.XPATH, '/html/body/form/div/div[2]/div[2]/div[1]/a[1]')
button.click()
msg = "打卡成功!\n请查看打卡记录:\n"
msg += parse_daka(driver)
print(msg)
send_email(msg, receiver)

if __name__ == '__main__':
user = ''
password = ''
receiver = ''
sleep_time = random.randint(1, 300)
print(f"{sleep_time} 秒后启动程序...")
time.sleep(sleep_time)
try:
daka(user, password, receiver)
except Exception as e:
msg = "未知异常,请检查!"
send_email(msg, receiver)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
from selenium.webdriver.chrome.service import Service
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup
from email.mime.text import MIMEText
from email.header import Header
from smtplib import SMTP_SSL
import random
import json
import requests
import os
import time
import cv2
import numpy as np


def send_email(msg, receiver):
host_server = '' # Email SMTP server
user = '' # user is the sender's email address
pwd = '' # pwd is the email authorization code
sender_mail = '' # sender's email
# Email body content
mail_content = msg

# Add bot signature
mail_sign = \
'''
\n
---

No need to reply!
Contact me: wgx@dijk.eu.org
'''

# Email title
mail_title = '【打卡消息推送】'
# SSL login
smtp = SMTP_SSL(host_server)
# set_debuglevel() is for debugging. A value of 1 enables debug mode, 0 disables it
smtp.set_debuglevel(0)
smtp.ehlo(host_server)
smtp.login(user, pwd)

msg = MIMEText(mail_content + mail_sign, "plain", 'utf-8')
msg["Subject"] = Header(mail_title, 'utf-8')
msg["From"] = sender_mail
msg["To"] = receiver
smtp.sendmail(sender_mail, receiver, msg.as_string())
smtp.quit()

def bin_img(img):
# Set the pure white threshold to 255 (note: OpenCV uses BGR, not RGB)
white_threshold = 246
# Find pixel positions that are not pure white by comparison
not_white = np.any(img < white_threshold, axis=-1)
# Create an all-black image
black_image = np.zeros_like(img)
# Set non-pure-white pixels to black, keep the rest unchanged (optional, if you only want to keep pure white pixels)
img[not_white] = [0, 0, 0]
return img

def download_image(url, filename):
response = requests.get(url)
if response.status_code == 200:
with open(filename, 'wb') as file:
file.write(response.content)

def match_img(big_image, small_image):
# Binarize images
big_image = bin_img(big_image)
small_image = bin_img(small_image)

# Use template matching to find the small image's position in the big image
result = cv2.matchTemplate(big_image, small_image, cv2.TM_CCOEFF_NORMED)

# Get the maximum value in the matching result and its position
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)

# Top-left point of the slider
top_left = max_loc

# Since we know the small image size, we can calculate the bottom-right corner of the matching region
# bottom_right = (top_left[0] + small_image.shape[1], top_left[1] + small_image.shape[0])

# # Draw the matched region on the big image
# cv2.rectangle(big_image, top_left, bottom_right, color=(0, 255, 0), thickness=2)

# Display the result
# cv2.imshow('Match', big_image)
# cv2.waitKey(0)
# cv2.destroyAllWindows()

xcenter_x = top_left[0] + small_image.shape[1] / 2
image_width = big_image.shape[1] # image.shape[1] gives the image width

# Calculate the percentage
percentage = (xcenter_x / image_width)

return percentage

def wait_for_page_load(driver, timeout=10):
try:
# Use WebDriverWait to wait for the page to load, by checking document.readyState == 'complete' via JavaScript
page_loaded = WebDriverWait(driver, timeout).until(
lambda d: d.execute_script('return document.readyState') == 'complete'
)
except TimeoutException:
print("Page did not fully load within the given time!")
return False
return True

def verify(percentage, driver):
slider_button = driver.find_element(By.CSS_SELECTOR, ".ui-slider-btn.init")
slider_track = driver.find_element(By.CSS_SELECTOR, ".ui-slider-wrap") # Assume the track element class is "ui-slider-wrap"
# Get the track length
track_width = slider_track.size['width']
# Calculate the pixel distance to drag
offset = track_width * percentage
# Initialize the ActionChains object
action_chains = ActionChains(driver)
# Click and hold the slider button
action_chains.click_and_hold(slider_button).perform()
# Add a very short delay here to simulate a very smooth human drag of the slider
for step in range(int(offset // 10)):
action_chains.move_by_offset(10, 0).perform() # Move in small steps
time.sleep(0.05) # Wait a bit to make the action visible
remaining_offset = offset % 10
action_chains.move_by_offset(remaining_offset, 0).perform() # Move the remaining distance
time.sleep(0.5) # Pause briefly after finishing the drag
action_chains.release().perform() # Release the slider

def is_passed(driver):
# Find the element containing the specified text
text_element = driver.find_element(By.CLASS_NAME, "ui-slider-text")
# Extract and print the text
slider_text = text_element.text
print(slider_text)
if slider_text[:4] == "验证成功":
return True
else:
return False

def login_recheck(driver):
elements = driver.find_elements(By.XPATH, '/html/body/form/div/div[2]/div[2]/table')
if len(elements) > 0:
return True
else:
return False

def parse_daka(driver):
# Assume html_content is the string containing the HTML shown above
html_content = driver.page_source
# Parse the HTML with BeautifulSoup
soup = BeautifulSoup(html_content, 'html.parser')
# Initialize the result list
result = []
# Find the table
table = soup.find('table', {'class': 'kq-message-table'})
# Get all th tags in the header for column names
headers = []
for th in table.find('thead').find_all('th'):
# For each th tag, get the text and strip spaces and newlines
headers.append(' '.join(th.stripped_strings))
# Iterate over each row of the table
for row in table.find('tbody').find_all('tr'):
# Get all td tags in the row
cells = row.find_all('td')
# Each row's data is stored as a dict, keys from headers, values from cell data
data = {}
for index, cell in enumerate(cells):
key = headers[index]
# Extract each cell's text as data
data[key] = cell.get_text(strip=True)
# Add each row's data to the result list
result.append(data)
# Convert the result list to JSON format
json_data = json.dumps(result, ensure_ascii=False, indent=4)
return json_data

def daka(user,password, receiver):
options = Options()
options.binary_location = '/opt/google/chrome/google-chrome'
options.add_argument('--headless')
options.add_argument("--disable-dev-shm-usage")
options.add_argument("--no-sandbox")
service = Service(executable_path='/daka/chromedriver')
driver = webdriver.Chrome(service=service,options=options)

retry = 0
verify_adjust = [0.03, 0.02, 0.01, -0.01, -0.02, -0.03]
adjust_index = 0
while True:
driver.get('http://kq.neusoft.com')
while not is_passed(driver):
big_image_elem = driver.find_element(By.ID, "bigImage")
small_image_elem = driver.find_element(By.ID, "smallImage")

big_image_url = big_image_elem.get_attribute("src")
small_image_url = small_image_elem.get_attribute("src")

download_image(big_image_url, "big.png")
download_image(small_image_url, "small.png")
time.sleep(5)

big_image = cv2.imread('big.png')
small_image = cv2.imread('small.png')

percent = match_img(big_image, small_image)
print(percent)
verify(percent - verify_adjust[adjust_index], driver)
time.sleep(2)

retry += 1
adjust_index = retry // 10
if adjust_index > 5:
send_email("Check-in failed: too many retries, giving up!",receiver)
return -1

print("Captcha passed!")
user_input_element = driver.find_element(By.XPATH, '/html/body/div[1]/form/div[2]/div/div/div[2]/div[2]/input')
user_input_element.send_keys(user)

pass_input_element = driver.find_element(By.XPATH, "/html/body/div[1]/form/div[2]/div/div/div[2]/div[3]/input")
pass_input_element.send_keys(password)

login_button = driver.find_element(By.XPATH, '/html/body/div[1]/form/div[2]/div/div/div[2]/div[6]/input')
login_button.click()
time.sleep(1)
if login_recheck(driver):
print("Login successful!")
break

time.sleep(2)
msg = parse_daka(driver)
button = driver.find_element(By.XPATH, '/html/body/form/div/div[2]/div[2]/div[1]/a[1]')
button.click()
msg = "Check-in successful!\nPlease check your check-in records:\n"
msg += parse_daka(driver)
print(msg)
send_email(msg, receiver)

if __name__ == '__main__':
user = ''
password = ''
receiver = ''
sleep_time = random.randint(1, 300)
print(f"{sleep_time} seconds until the program starts...")
time.sleep(sleep_time)
try:
daka(user, password, receiver)
except Exception as e:
msg = "Unknown exception, please check!"
send_email(msg, receiver)