链工宝优化

本文介绍如何使用油猴脚自动检测链工宝平台的人脸识别弹窗,并通过OBS Studio进行人脸识别验证。

脚本功能说明

该脚本主要实现以下功能:

  1. 自动检测链工宝平台的人脸识别二维码弹窗
  2. 在新标签页中打开二维码中的URL,方便使用OBS Studio进行人脸识别验证
  3. 弹窗关闭后自动点击视频播放和继续观看按钮
  4. 监控视频播放时间,防止播放卡住
  5. 在cdn.lgb360.com域名下自动点击拍照按钮并在验证成功后关闭网页

代码详解

参考代码如下:

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
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
// ==UserScript==
// @name 弹窗检测并自动操作
// @namespace http://tampermonkey.net/
// @version 1.9
// @description 检测网站的弹窗并自动在新标签页打开URL,弹窗消失后自动点击播放和继续观看按钮,监控播放时间
// @author Kb
// @match https://www.lgb360.com/*
// @grant none
// ==/UserScript==

(function() {
'use strict';

// 要检测的弹窗元素XPath - 直接定位包含title的qr-code元素
const TARGET_POPUP_XPATH = '//div[contains(@class, "qr-code") and @title]';

// 备用XPath - 原来的路径
const BACKUP_POPUP_XPATH = '//*[@id="app"]/div/div[2]/div[1]/div[4]/div/div[2]/div/div[2]/div[1]//div[contains(@class, "qr-code")]';

// 播放按钮选择器
const PLAY_BUTTON_SELECTOR = '.pv-playpause.pv-iconfont.pv-icon-btn-play';

// 继续观看按钮选择器
const CONTINUE_BUTTON_SELECTOR = '.el-button.el-button--primary';
const CONTINUE_BUTTON_TEXT = '继续观看';

// 播放时间选择器
const CURRENT_TIME_SELECTOR = '.pv-time-current';

let popupDetected = false;
let lastDetectedTitle = '';
let playButtonClicked = false;
let continueButtonClicked = false;
let lastPlayTime = '';
let timeCheckCounter = 0;
const MAX_TIME_CHECKS = 5; // 最大检查次数

// 通过XPath查找元素
function getElementByXpath(path) {
return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}

// 查找包含title的二维码元素
function findQrCodeWithTitle() {
const qrCodeElements = document.querySelectorAll('.qr-code[title]');
for (let el of qrCodeElements) {
const style = window.getComputedStyle(el);
const visible = (
style.display !== 'none' &&
style.visibility !== 'hidden' &&
parseFloat(style.opacity) > 0 &&
el.offsetParent !== null
);
if (visible) {
return el; // ✅ 返回第一个真正可见的二维码
}
}
return null;
}

// 查找播放按钮
function findPlayButton() {
const playButton = document.querySelector(PLAY_BUTTON_SELECTOR);
if (playButton) {
console.log('找到播放按钮:', playButton);
return playButton;
}
return null;
}

// 查找继续观看按钮
function findContinueButton() {
const buttons = document.querySelectorAll(CONTINUE_BUTTON_SELECTOR);
for (let button of buttons) {
const span = button.querySelector('span');
if (span && span.textContent.trim() === CONTINUE_BUTTON_TEXT) {
console.log('找到继续观看按钮:', button);
return button;
}
}
return null;
}

// 获取当前播放时间
function getCurrentPlayTime() {
const timeElement = document.querySelector(CURRENT_TIME_SELECTOR);
if (timeElement) {
return timeElement.textContent.trim();
}
return null;
}

// 检查播放时间是否变化
function checkPlayTimeChanged() {
const currentTime = getCurrentPlayTime();
console.log('当前播放时间:', currentTime, '上次播放时间:', lastPlayTime);

if (currentTime) {
if (lastPlayTime === '') {
// 第一次获取时间,记录下来
lastPlayTime = currentTime;
timeCheckCounter = 1;
console.log('初始化播放时间:', currentTime);
return false;
} else if (currentTime !== lastPlayTime) {
// 时间发生变化
console.log('播放时间发生变化:', lastPlayTime, '->', currentTime);
lastPlayTime = currentTime;
timeCheckCounter = 0; // 重置计数器
return true;
} else {
// 时间没有变化
timeCheckCounter++;
console.log(`播放时间未变化 (${timeCheckCounter}/${MAX_TIME_CHECKS}):`, currentTime);

// 如果连续多次时间没有变化,认为播放卡住了
if (timeCheckCounter >= MAX_TIME_CHECKS) {
console.log('播放可能卡住,尝试重新点击播放按钮');
return false; // 返回false表示需要重新点击
}
return true; // 返回true表示时间在正常变化
}
}
return false; // 没有找到时间元素
}

// 点击播放按钮
function clickPlayButton() {
if (playButtonClicked && timeCheckCounter < MAX_TIME_CHECKS) {
return false;
}

const playButton = findPlayButton();
if (playButton) {
try {
playButton.click();
console.log('成功点击播放按钮');
playButtonClicked = true;
lastPlayTime = ''; // 重置时间记录
timeCheckCounter = 0; // 重置计数器
showNotification('已自动点击播放按钮');
return true;
} catch (error) {
console.error('点击播放按钮时出错:', error);
// 尝试模拟点击
return simulateClick(playButton);
}
}
return false;
}

// 点击继续观看按钮
function clickContinueButton() {
if (continueButtonClicked) {
return false;
}

const continueButton = findContinueButton();
if (continueButton) {
try {
continueButton.click();
console.log('成功点击继续观看按钮');
continueButtonClicked = true;
showNotification('已自动点击继续观看按钮');
return true;
} catch (error) {
console.error('点击继续观看按钮时出错:', error);
// 尝试模拟点击
return simulateClick(continueButton);
}
}
return false;
}

// 模拟点击事件
function simulateClick(element) {
try {
console.log('尝试模拟点击事件');
const mouseEvent = new MouseEvent('click', {
view: window,
bubbles: true,
cancelable: true
});
element.dispatchEvent(mouseEvent);
console.log('模拟点击成功');
return true;
} catch (error) {
console.error('模拟点击失败:', error);
return false;
}
}

// 在新标签页打开URL
function openUrlInNewTab(url) {
if (url && url.startsWith('http')) {
console.log('在新标签页打开URL:', url);
window.open(url, '_blank');
return true;
}
return false;
}

// 显示通知
function showNotification(message) {
const notification = document.createElement('div');
notification.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: #4CAF50;
color: white;
padding: 10px 20px;
border-radius: 5px;
z-index: 10000;
font-family: Arial, sans-serif;
font-size: 14px;
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
`;
notification.textContent = message;

document.body.appendChild(notification);

setTimeout(() => {
if (notification.parentNode) {
notification.parentNode.removeChild(notification);
}
}, 3000);
}

// 检查播放状态
function checkPlayStatus() {
// 修改:只有当没有弹窗且已点击播放按钮时才检查播放状态
if (!popupDetected && playButtonClicked) {
const timeChanged = checkPlayTimeChanged();
if (!timeChanged && timeCheckCounter >= MAX_TIME_CHECKS) {
console.log('播放可能卡住,重新点击播放按钮');
playButtonClicked = false; // 允许重新点击
setTimeout(() => {
clickPlayButton();
}, 1000);
}
}
}

// 检查弹窗函数
function checkPopup() {
const qrCodeElement = findQrCodeWithTitle();

// 检查是否有可见弹窗
const visible = qrCodeElement && window.getComputedStyle(qrCodeElement).display !== 'none';

if (visible) {
const currentTitle = qrCodeElement.getAttribute('title');
console.log('当前检测到的title:', currentTitle);

if (currentTitle && currentTitle !== lastDetectedTitle) {
popupDetected = true;
lastDetectedTitle = currentTitle;
playButtonClicked = false;
continueButtonClicked = false;
lastPlayTime = '';
timeCheckCounter = 0;

console.log('检测到新的二维码弹窗,title:', currentTitle);

// 在新标签页打开URL
if (openUrlInNewTab(currentTitle)) {
console.log('成功在新标签页打开URL');
} else {
console.log('URL格式不正确,无法打开:', currentTitle);
}
}
} else {
// ✅ 只有从"检测到弹窗"→"弹窗消失"时才执行播放逻辑
if (popupDetected) {
console.log('弹窗已关闭');
popupDetected = false;
lastDetectedTitle = '';

// 弹窗消失后尝试点击播放按钮和继续观看按钮
setTimeout(() => {
if (!playButtonClicked) {
clickPlayButton();
}
if (!continueButtonClicked) {
setTimeout(() => {
clickContinueButton();
}, 1000);
}
}, 1000);
}
}

// ✅ 弹窗不存在时执行播放状态检测
if (!popupDetected) {
checkPlayStatus();

// 如果播放按钮未点,尝试自动点击
if (!playButtonClicked) {
setTimeout(() => {
clickPlayButton();
}, 2000);
}
if (!continueButtonClicked) {
setTimeout(() => {
clickContinueButton();
}, 3000);
}
}
}


// 使用MutationObserver监听DOM变化
function startMonitoring() {
console.log('开始监控二维码弹窗、播放按钮和继续观看按钮...');

// 立即检查一次
checkPopup();

// 创建观察器实例
const observer = new MutationObserver(function(mutations) {
let shouldCheckPopup = false;
let shouldCheckPlayButton = false;
let shouldCheckContinueButton = false;

mutations.forEach(function(mutation) {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach(function(node) {
if (node.nodeType === 1) {
// 检查是否添加了二维码元素
if (node.matches && node.matches('.qr-code')) {
shouldCheckPopup = true;
} else if (node.querySelector && node.querySelector('.qr-code')) {
shouldCheckPopup = true;
}

// 检查是否添加了播放按钮
if (node.matches && node.matches(PLAY_BUTTON_SELECTOR)) {
shouldCheckPlayButton = true;
} else if (node.querySelector && node.querySelector(PLAY_BUTTON_SELECTOR)) {
shouldCheckPlayButton = true;
}

// 检查是否添加了继续观看按钮
if (node.matches && node.matches(CONTINUE_BUTTON_SELECTOR)) {
shouldCheckContinueButton = true;
} else if (node.querySelector && node.querySelector(CONTINUE_BUTTON_SELECTOR)) {
shouldCheckContinueButton = true;
}
}
});

// 检查是否移除了二维码元素(弹窗关闭)
mutation.removedNodes.forEach(function(node) {
if (node.nodeType === 1) {
if (node.matches && node.matches('.qr-code')) {
shouldCheckPopup = true;
} else if (node.querySelector && node.querySelector('.qr-code')) {
shouldCheckPopup = true;
}
}
});
}
});

if (shouldCheckPopup) {
setTimeout(checkPopup, 500);
}

if (shouldCheckPlayButton && !playButtonClicked) {
setTimeout(() => {
clickPlayButton();
}, 500);
}

if (shouldCheckContinueButton && !continueButtonClicked) {
setTimeout(() => {
clickContinueButton();
}, 500);
}
});

// 开始观察整个document
observer.observe(document.body, {
childList: true,
subtree: true
});

// 同时使用定时器作为备用检测
setInterval(checkPopup, 3000);

// 单独设置播放时间检查定时器(更频繁)
setInterval(checkPlayStatus, 5000);
}

// 初始化函数
function init() {
console.log('弹窗检测脚本初始化完成,开始监控');
startMonitoring();
}

// 页面加载完成后开始初始化
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}

// 添加调试函数
window.debugQrCode = function() {
console.log('=== 二维码元素调试信息 ===');

const methods = [
{ name: '主XPath', element: getElementByXpath(TARGET_POPUP_XPATH) },
{ name: '备用XPath', element: getElementByXpath(BACKUP_POPUP_XPATH) },
{ name: 'CSS选择器', element: document.querySelector('.qr-code[title]') },
{ name: '所有qr-code', elements: document.querySelectorAll('.qr-code') }
];

methods.forEach(method => {
console.log(`\n${method.name}:`);
if (method.elements) {
console.log(`找到 ${method.elements.length} 个.qr-code元素`);
method.elements.forEach((el, index) => {
const title = el.getAttribute('title');
console.log(` ${index + 1}. ${el.outerHTML.substring(0, 200)}`);
console.log(` title: ${title}`);
console.log(` 有title属性: ${el.hasAttribute('title')}`);
});
} else if (method.element) {
const title = method.element.getAttribute('title');
console.log(`找到元素:`, method.element);
console.log(`outerHTML:`, method.element.outerHTML);
console.log(`title属性:`, title);
console.log(`有title属性:`, method.element.hasAttribute('title'));
} else {
console.log('未找到元素');
}
});
};

// 手动打开URL函数
window.openDetectedUrl = function() {
const qrCodeElement = findQrCodeWithTitle();
if (qrCodeElement) {
const url = qrCodeElement.getAttribute('title');
if (url) {
console.log('手动打开URL:', url);
return openUrlInNewTab(url);
} else {
console.log('找到元素但没有title属性');
return false;
}
} else {
console.log('未找到二维码元素');
return false;
}
};

// 手动点击播放按钮
window.clickPlayButtonManually = function() {
console.log('手动触发播放按钮点击');
playButtonClicked = false;
lastPlayTime = '';
timeCheckCounter = 0;
return clickPlayButton();
};

// 手动点击继续观看按钮
window.clickContinueButtonManually = function() {
console.log('手动触发继续观看按钮点击');
continueButtonClicked = false;
return clickContinueButton();
};

// 显示当前状态
window.showPopupStatus = function() {
console.log('=== 弹窗检测状态 ===');
console.log('弹窗检测状态:', popupDetected ? '已检测到弹窗' : '未检测到弹窗');
console.log('最后检测到的URL:', lastDetectedTitle || '无');
console.log('播放按钮状态:', playButtonClicked ? '已点击' : '未点击');
console.log('继续观看按钮状态:', continueButtonClicked ? '已点击' : '未点击');
console.log('当前播放时间:', getCurrentPlayTime() || '无');
console.log('上次播放时间:', lastPlayTime || '无');
console.log('时间检查计数:', timeCheckCounter);

const qrCodeElement = findQrCodeWithTitle();
if (qrCodeElement) {
const url = qrCodeElement.getAttribute('title');
console.log('当前可用的URL:', url || '无');
} else {
console.log('当前没有可用的二维码元素');
}

const playButton = findPlayButton();
if (playButton) {
console.log('播放按钮存在:', playButton);
} else {
console.log('播放按钮不存在');
}

const continueButton = findContinueButton();
if (continueButton) {
console.log('继续观看按钮存在:', continueButton);
} else {
console.log('继续观看按钮不存在');
}

const timeElement = document.querySelector(CURRENT_TIME_SELECTOR);
if (timeElement) {
console.log('播放时间元素存在:', timeElement);
console.log('播放时间文本:', timeElement.textContent.trim());
} else {
console.log('播放时间元素不存在');
}
};
})();
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
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
// ==UserScript==
// @name 自动点击拍照按钮并关闭网页
// @namespace http://tampermonkey.net/
// @version 1.1
// @description 在cdn.lgb360.com域名下自动点击拍照按钮,验证成功后关闭网页
// @author Kb
// @match https://cdn.lgb360.com/*
// @grant none
// ==/UserScript==

(function() {
'use strict';

// 目标按钮的选择器
const TARGET_BUTTON_SELECTOR = '.van-button__content .van-button__text';
const BUTTON_TEXT = '点击拍照';

// 验证成功元素的选择器
const SUCCESS_SELECTOR = '.result-title';
const SUCCESS_TEXT = '验证成功';

let buttonClicked = false;
let successDetected = false;

// 查找并点击按钮
function findAndClickButton() {
// 如果已经点击过,不再重复点击
if (buttonClicked) {
return;
}

// 查找所有包含指定文本的按钮
const buttons = document.querySelectorAll(TARGET_BUTTON_SELECTOR);

for (let button of buttons) {
if (button.textContent.trim() === BUTTON_TEXT) {
console.log('找到拍照按钮:', button);

// 尝试点击按钮
try {
button.click();
console.log('成功点击拍照按钮');
buttonClicked = true;

// 显示成功消息
showNotification('已自动点击拍照按钮');
return true;
} catch (error) {
console.error('点击按钮时出错:', error);

// 如果直接点击失败,尝试模拟鼠标事件
simulateClick(button);
return true;
}
}
}

return false;
}

// 检查验证成功
function checkVerificationSuccess() {
if (successDetected) {
return true;
}

const successElements = document.querySelectorAll(SUCCESS_SELECTOR);

for (let element of successElements) {
if (element.textContent.trim() === SUCCESS_TEXT) {
console.log('检测到验证成功:', element);
successDetected = true;

// 显示通知
showNotification('验证成功,即将关闭页面');

// 2秒后关闭网页
setTimeout(() => {
console.log('关闭当前网页');
window.close();

// 如果window.close()无效,尝试其他方法
setTimeout(() => {
if (!window.closed) {
console.log('window.close()无效,尝试其他方法');
// 尝试返回上一页或跳转到空白页
window.history.back();
}
}, 1000);
}, 2000);

return true;
}
}

return false;
}

// 模拟点击事件(备用方法)
function simulateClick(element) {
try {
console.log('尝试模拟点击事件');

// 创建鼠标事件
const mouseEvent = new MouseEvent('click', {
view: window,
bubbles: true,
cancelable: true
});

// 分发事件
element.dispatchEvent(mouseEvent);
buttonClicked = true;
console.log('模拟点击成功');
showNotification('已通过模拟事件点击拍照按钮');
} catch (error) {
console.error('模拟点击失败:', error);
}
}

// 显示通知
function showNotification(message) {
// 创建简单的通知元素
const notification = document.createElement('div');
notification.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: #4CAF50;
color: white;
padding: 10px 20px;
border-radius: 5px;
z-index: 10000;
font-family: Arial, sans-serif;
font-size: 14px;
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
`;
notification.textContent = message;

document.body.appendChild(notification);

// 3秒后自动移除
setTimeout(() => {
if (notification.parentNode) {
notification.parentNode.removeChild(notification);
}
}, 3000);
}

// 使用MutationObserver监听DOM变化
function startMonitoring() {
console.log('开始监控拍照按钮和验证成功状态...');

// 立即检查一次
if (findAndClickButton()) {
return;
}

// 检查验证成功
checkVerificationSuccess();

// 创建观察器实例
const observer = new MutationObserver(function(mutations) {
let shouldCheckButton = false;
let shouldCheckSuccess = false;

mutations.forEach(function(mutation) {
if (mutation.type === 'childList') {
// 检查新增的节点是否包含目标按钮或成功元素
mutation.addedNodes.forEach(function(node) {
if (node.nodeType === 1) { // 元素节点
// 检查拍照按钮
if (node.matches && (node.matches(TARGET_BUTTON_SELECTOR) ||
node.querySelector && node.querySelector(TARGET_BUTTON_SELECTOR))) {
shouldCheckButton = true;
}

// 检查验证成功元素
if (node.matches && (node.matches(SUCCESS_SELECTOR) ||
node.querySelector && node.querySelector(SUCCESS_SELECTOR))) {
shouldCheckSuccess = true;
}
}
});
}
});

if (shouldCheckButton && !buttonClicked) {
setTimeout(() => {
findAndClickButton();
}, 500);
}

if (shouldCheckSuccess && !successDetected) {
setTimeout(() => {
checkVerificationSuccess();
}, 500);
}
});

// 开始观察整个document
observer.observe(document.body, {
childList: true,
subtree: true
});

// 同时使用定时器作为备用检测
const checkInterval = setInterval(() => {
if (!buttonClicked) {
findAndClickButton();
}

if (!successDetected) {
checkVerificationSuccess();
}

// 如果验证成功或超过30秒,停止检测
if (successDetected) {
clearInterval(checkInterval);
}
}, 2000);

// 30秒后停止检测,避免无限循环
setTimeout(() => {
if (!successDetected) {
clearInterval(checkInterval);
console.log('30秒内未完成验证,停止检测');
if (!buttonClicked) {
showNotification('未找到拍照按钮,请手动操作');
} else {
showNotification('等待验证超时,请手动检查');
}
}
}, 30000);
}

// 页面加载完成后开始监控
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', startMonitoring);
} else {
startMonitoring();
}

// 添加手动触发函数
window.manualClickPhotoButton = function() {
console.log('手动触发拍照按钮点击');
buttonClicked = false; // 重置状态,允许重新点击
return findAndClickButton();
};

// 手动检查验证状态
window.checkSuccessManually = function() {
console.log('手动检查验证状态');
return checkVerificationSuccess();
};

// 手动关闭网页
window.closePageManually = function() {
console.log('手动关闭网页');
window.close();
};

// 显示当前状态
window.showButtonStatus = function() {
console.log('=== 按钮检测状态 ===');
console.log('按钮点击状态:', buttonClicked ? '已点击' : '未点击');
console.log('验证成功状态:', successDetected ? '已验证成功' : '未验证成功');

const buttons = document.querySelectorAll(TARGET_BUTTON_SELECTOR);
console.log(`找到 ${buttons.length} 个匹配选择器的元素`);

buttons.forEach((button, index) => {
console.log(`按钮 ${index + 1}:`, {
text: button.textContent.trim(),
element: button,
isTarget: button.textContent.trim() === BUTTON_TEXT
});
});

const successElements = document.querySelectorAll(SUCCESS_SELECTOR);
console.log(`找到 ${successElements.length} 个验证结果元素`);

successElements.forEach((element, index) => {
console.log(`验证元素 ${index + 1}:`, {
text: element.textContent.trim(),
element: element,
isSuccess: element.textContent.trim() === SUCCESS_TEXT
});
});

if (buttons.length === 0) {
console.log('未找到任何匹配选择器的按钮');
}
};
console.log('自动点击拍照按钮脚本已加载');
})();

OBS Studio 配置说明

为了实现人脸识别验证,需要配置OBS Studio进行屏幕捕捉并将视频流传输到链工宝平台。具体步骤如下:

  1. 安装OBS Studio

  2. 配置场景和来源

    • 创建新场景或使用现有场景
    • 点击”来源”面板中的”+”按钮
    • 选择”显示器捕获”或”窗口捕获”(根据需要选择捕获整个桌面或特定窗口)
    • 如果使用”显示器捕获”,选择要捕获的显示器
    • 如果使用”窗口捕获”,选择包含您面部的摄像头窗口
  3. 调整图片设置

    • 在”设置” > “视频”中调整基础分辨率和输出分辨率
    • 设置合适的图片
    • 确保分辨率适合人脸识别(建议至少640x480)
  1. 在链工宝平台使用虚拟摄像头

    • 当链工宝弹出人脸识别窗口时,选择虚拟摄像头作为视频源
    • 确保OBS Studio中的预览显示正确的视频画面
  2. 优化设置

    • 根据需要添加滤镜(如色彩校正)以提高图像质量
    • 确保光线充足,避免过曝或过暗
    • 保持面部在画面中心位置

脚本工作原理

  1. 元素检测机制:脚本使用多种策略来查找页面中的人脸识别二维码弹窗:

    • 通过XPath直接查找包含title属性的qr-code元素
    • 使用备用XPath路径查找元素
    • 使用CSS选择器查找元素
    • 遍历所有qr-code元素查找包含title属性的元素
  2. 变化监听机制

    • 使用MutationObserver监听DOM变化,当有新的qr-code元素添加到页面时立即检测
    • 同时使用定时器定期检查,确保不会遗漏弹窗
  3. 自动化操作流程

    • 检测到二维码弹窗后,自动在新标签页中打开URL
    • 弹窗关闭后,自动点击视频播放按钮
    • 监控播放时间,如果发现播放卡住会自动重新点击播放按钮
    • 自动点击继续观看按钮以确保学习进度正常
  4. 拍照验证自动化

    • 在cdn.lgb360.com域名下自动检测拍照按钮
    • 点击拍照按钮完成人脸识别验证
    • 验证成功后自动关闭网页

使用步骤

  1. 安装油猴插件

    • 在浏览器中安装Tampermonkey插件(Chrome/Edge/Firefox均支持)
    • 确保插件已正确安装并启用
  2. 安装脚本

    • 创建新的用户脚本
    • 将上述JavaScript代码复制到脚本编辑器中
    • 保存脚本并确保在油猴中已启用
  3. 配置OBS Studio

    • 按照上述说明配置OBS Studio
    • 启动虚拟摄像头功能
    • 确保视频预览正常
  4. 使用链工宝平台

    • 登录链工宝平台开始学习
    • 当出现人脸识别弹窗时,脚本会自动处理
    • 无需手动干预,脚本会完成所有操作
  5. 监控脚本运行

    • 可以通过浏览器开发者工具的控制台查看脚本运行日志
    • 使用提供的调试函数检查脚本状态

注意事项

  1. 请确保使用Chrome浏览器以获得最佳兼容性
  2. 脚本只在链工宝网站(https://www.lgb360.com/*)上运行
  3. 由于链工宝网站可能会更新页面结构,如果脚本失效,请检查XPath路径是否需要调整
  4. OBS Studio需要正确配置才能实现人脸识别验证
  5. 脚本会定期检查页面元素,可能会对页面性能产生轻微影响

可能遇到的问题及解决方法

  1. 二维码弹窗未被检测到

    • 检查控制台是否有错误信息
    • 使用window.debugQrCode()函数调试二维码元素
    • 确认页面元素结构是否发生变化
  2. 元素查找失败

    • 链工宝网站更新了页面结构,需要更新XPath路径
    • 可以通过浏览器开发者工具检查qr-code元素的实际路径
    • 更新脚本中的选择器以匹配新的页面结构
  3. 播放按钮点击失败

    • 使用window.clickPlayButtonManually()手动触发点击
    • 检查PLAY_BUTTON_SELECTOR是否正确匹配页面元素
    • 确认页面是否有其他元素遮挡了播放按钮
  4. 脚本不运行

    • 确认油猴插件已正确安装并启用
    • 检查脚本的@match规则是否匹配当前网址
    • 确认脚本在油猴中已启用
  5. OBS Studio配置问题

    • 确认虚拟摄像头插件已正确安装
    • 检查摄像头是否被其他程序占用
    • 确认链工宝平台选择了正确的视频源

通过以上配置和使用说明,您可以成功使用该脚本来监控链工宝平台的人脸识别弹窗,并及时收到钉钉通知。

安全声明

⚠️ 重要声明

  1. 本脚本仅供学习和研究目的使用,旨在帮助理解网页自动化技术和通知机制的实现原理。

  2. 用户在使用本脚本时,必须确保遵守链工宝平台的用户协议和相关服务条款,不得用于任何违反平台规定的行为。

  3. 任何使用本脚本进行非法用途的行为均与作者无关,用户需自行承担相应的法律责任。

  4. 请严格遵守《中华人民共和国网络安全法》、《计算机软件保护条例》等相关法律法规,合法合规地使用技术工具。

  5. 建议用户在使用前充分了解相关平台的反爬虫机制和使用规范,避免对平台造成不必要的负担或违反服务条款。

  6. 作者不对因使用本脚本而导致的任何直接或间接损失负责,包括但不限于账号封禁、数据丢失、财产损失等。

请在合法合规的前提下,合理使用技术工具进行学习和研究.