首页
社区
课程
招聘
[原创]OpenCD(皇后)签到脚本(配合魂签-模拟点击)与我的本地音乐方案
发表于: 2024-8-19 10:36 1851

[原创]OpenCD(皇后)签到脚本(配合魂签-模拟点击)与我的本地音乐方案

2024-8-19 10:36
1851

0.开始之前

首先,皇后的签到和其他站点不太一样
网站的基本实现是:
签到按钮,弹出iframe,里面有验证码,输入后点确定

1.验证码

感谢前辈的肩膀,让我可以方便的搞定这个
ddddocr

2.iframe问题

经过搜索,发现可以操作iframe,也不算复杂
调试魂签,发现浏览器打开标签页后返回的对象,有eval方法
绝妙!

3.成品

github
逻辑不多

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
// ==UserScript==
// @name              OpenCD签到
// @namespace        
// @version           0.0.1
// @author           
// @loginURL         
// @updateURL        
// @expire            900000
// @grant             cookie
// @domain            open.cd
// @domain            2045.site
// @domain            uimstest.2045.site
// @domain            uimstest.2045.site:5001
// @param             name
// @param             pwd
// ==/UserScript==
 
const opts = { headers: { referer: "https://open.cd/" } };
exports.run = async function (param) {
    // 使用浏览器打开登录界面,并获取窗口句柄
    return await open("https://open.cd/", /** 调试时设置成true */ false, async (fb) => {
        var rate = 0.5; // 间隔时间倍率,值越小脚本执行越快
        await fb.sleep(1800 * rate)
        let signInResult = await fb.eval(checkResult);
        if (signInResult.includes("已签到") || signInResult.includes("签到记录")) {
            return "签到成功";
        }
        if (!await fb.click("#info_block > tbody > tr > td > table > tbody > tr > td:nth-child(3) > div:nth-child(2) > a:nth-child(1)")) throw '签到失败'
        await fb.sleep(1600 * rate)
        var imgSrc = await fb.eval(getImgSrc);
        if (imgSrc == null) {
            var tryCount = 0;
            while (tryCount < 3) {
                tryCount++;
                await fb.sleep(500 * rate)
                imgSrc = await fb.eval(getImgSrc);
                if (imgSrc != null) {
                    break;
                }
            }
        }
        if (imgSrc == null) {
            throw "获取验证码失败";
        }
        var file = await imageUrlToFile(imgSrc, 'temp');
        var reqResult = await uploadFileInfo(file);
        if (reqResult.result && reqResult.result.length == 6) {
            var jsCode = "document.getElementById(\"i_signin\").contentWindow.document.querySelector('#imagestring').value = \"" + reqResult.result + "\"";
            fb.eval(jsCode)
            await fb.sleep(1500 * rate)
            jsCode = "document.getElementById(\"i_signin\").contentWindow.document.querySelector('#ok').click()";
            fb.eval(jsCode)
            await fb.sleep(1500 * rate)
            let signInResult = await fb.eval(checkResult);
            if (signInResult.includes("已签到") || signInResult.includes("签到记录")) {
                return "签到成功";
            }
            throw result;
        }
        throw reqResult;
    });
};
 
function getImgSrc() {
    var img = document.getElementById("i_signin").contentWindow.document.querySelector('#frmSignin > table > tbody > tr > td > img');
    if (img == null) {
        return null;
    }
    return img.src;
}
 
function checkResult() {
    let element = document.querySelector("#info_block > tbody > tr > td > table > tbody > tr > td:nth-child(3) > div:nth-child(2) > a:nth-child(1)");
    return element.textContent
}
 
async function imageUrlToFile(url, fileName) {
    try {
        const response = await axios.get(url, { responseType: 'arraybuffer' })
        const imageData = response.data
        const blob = new Blob([imageData], {
            type: response.headers['content-type']
        })
        const file = new File([blob], fileName, { type: blob.type })
        return file
    } catch (error) {
        console.error('将图片转换为File对象时发生错误:', error)
        throw error
    }
}
 
async function uploadFileInfo(file) {
    let formData = new FormData();
    formData.append("image", file);
    // 这里是使用ddddocr部署的OCR识别(https://github.com/sml2h3/ddddocr)
    let ocrUrl = 'http://uimstest.2045.site:5001/ocr'
    var { data } = await axios.post(ocrUrl, formData)
    return data
}
 
 
exports.check = async function (param) {
 
};

总结

整体逻辑不复杂,但苦于魂签没有文档(或者说我没找到),只能自己debug去看api,这可不太妙

后记

话说几天前,突然灵机一动,不想续音乐会员了
于是开始找PT站,大家都说皇后是内地音乐大站
于是......
RMB180...
蹲点,斥巨资(RMB180)捐入
然后发现,确实不适合我这种,只想上下班路上听歌的人...
但捐了也不能反悔不是,于是想着搜一个签到脚本挂着,就好了,结果没找到合适的...
一怒之下,决定自己来,才有了本帖...

那可能有朋友会好奇,我开会员了吗?
当然,木有
最终选择了一个(成熟?)方案(群辉的Audio Station)
RMB180...
虽然我也有plex,但目前不可用,它不认可我本地的音乐数据...
RMB180...
看小图就能知道,显然没识别

如果哪位有觉得好用的本地音乐方案,还请不吝赐教

bye


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2024-8-19 10:45 被mb_yasgsjvq编辑 ,原因: 更新标题
收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//