之前研究了一下OpenCD的签到方式,签到地址是这个,可以自行查看并分析其逻辑

1
https://open.cd/plugin_sign-in.php

界面逻辑还是很简单的,另外验证码也很干净

那么我们只需要用到自建的ddddocr-fastapi+脚本就能做到自动识别验证码后签到了,存档一下完整代码:

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
import base64
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin

BASE_URL = "https://open.cd/"
SIGNIN_PAGE = "plugin_sign-in.php"
SIGNIN_POST = "plugin_sign-in.php?cmd=signin"
#自己填OCR服务,用的ddddocr-fastapi
OCR_API = "http://127.0.0.1:8000/ocr"

HEADERS = {
# 自己填
}

COOKIES = {
# 自己填
}

def get_imagehash_and_img(session):
r = session.get(urljoin(BASE_URL, SIGNIN_PAGE))
r.raise_for_status()

soup = BeautifulSoup(r.text, "lxml")

imagehash = soup.find("input", {"name": "imagehash"})["value"]
img_src = soup.find("img")["src"]

img_url = urljoin(BASE_URL, img_src)
return imagehash, img_url

def download_captcha(session, img_url):
r = session.get(img_url)
r.raise_for_status()
return r.content

def image_to_base64(img_bytes):
# print(base64.b64encode(img_bytes).decode("utf-8"))
return base64.b64encode(img_bytes).decode("utf-8")

def ocr_image(image_b64):
files = {
"image": (None, image_b64),
"probability": (None, "false"),
"charsets": (None, ""),
"png_fix": (None, "false"),
}

headers = {
"Accept": "application/json",
}

r = requests.post(OCR_API, files=files, headers=headers, timeout=20)
r.raise_for_status()

data = r.json()
if data.get("code") != 200:
raise RuntimeError(f"OCR failed: {data}")

return data["data"]

def post_signin(session, imagehash, imagestring):
data = {
"imagehash": imagehash,
"imagestring": imagestring,
}

r = session.post(BASE_URL, files={
"imagehash": (None, imagehash),
"imagestring": (None, imagestring)
})
print(data)
# print(r.request.headers)
# print(r.request.body)
r.raise_for_status()
return r.text

def main():
session = requests.Session()
session.headers.update(HEADERS)
session.cookies.update(COOKIES)

max_retry = 5

for i in range(max_retry):
print(f"[*] 第 {i+1} 次尝试")

imagehash, img_url = get_imagehash_and_img(session)
img_bytes = download_captcha(session, img_url)
img_b64 = image_to_base64(img_bytes)
imagestring = ocr_image(img_b64)

result_html = post_signin(session, imagehash, imagestring)

if "验证码错误" not in result_html:
print("[✓] 成功")
return
else:
print("[!] 验证码错误,重试")

print("[✗] 多次尝试失败")


if __name__ == "__main__":
main()