前言

本文章实现需要服务器, 无可视化界面亦可。
使用的Cookie获取上一篇文章有介绍, 顺手写了这篇。

每日一问: 我为什么要实现这个功能???

机制分析

网页版状态下阅读, 每分钟左右会有一个read请求, 通过回执可以判断是否阅读成功。
具体参数我不想耗费时间去逆向, 但是可以通过模拟浏览阅读页面来等待read响应进行read重播,进而轻易实现自动阅读。

稳定性

服务器测试了24小时, 阅读时间也是相应增加24。

有趣的是, 经测试, 每次程序运行5min, 增加的时长可能是 5min、6min、8min、11min、13min 甚至是 21min。
但是总时长是稳定的, 也就是说会回归一天能拉满的时间24h。

实现代码

虽说是浏览器模拟事件, 到了python的表演时间, 但是我采用了JS去写, 辅佐包是 Playwright
总体是一次有趣的尝试。

准备事项

开始吧, 安装 Playwright

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 先创建一个文件夹
mkdir /server/auto/wxread && cd /server/auto/wxread

# 安装 playwright
npm install playwright
npx playwright install
# 下面这个可能需要点时间
# 因为有浏览器的下载
npx playwright install-deps

# 当然少不了 axios
npm install axios

# 好的, 一切准备就绪, 创建代码吧

代码

wxread.js
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
const { firefox } = require('playwright');
const axios = require('axios');

// 获取命令行参数
const args = process.argv.slice(2);
const params = {};
args.forEach((arg) => {
const [key, value] = arg.split('=');
if (key && value) {
params[key] = value;
}
});

const url1 = 'https://weread.qq.com/web/reader/8f5329e0813ab7d1eg012feake4d32d5015e4da3b7fbb1fa';
const url2 = 'https://weread.qq.com/web/book/read';
let capturedResponse = null;
let browser = null;

const scrollInterval = 10000; // 上下滑动间隔时间 单位毫秒
const totalTime = 400000; // 单次阅读时间 单位毫秒

const getXHR = async () => {
console.log("Success: 启动 Playwright 浏览器");
browser = await firefox.launch({
headless: true,
});
const page = await browser.newPage();
await page.setExtraHTTPHeaders({
cookie: (await axios.get("https://sijnzx.laf.thatcoder.cn/tencent-weread-refcookie?key="+params['key'])).data["data"]["cookies"]
});
await page.goto(url1, {
waitUntil: 'networkidle',
});

console.log("Success: 打开内容页面");
page.on('response', async (response) => {
if (response.url() === url2) {
const data = await response.json();
if (data['succ'] === 1) {
console.log("Success: 目标URL响应成功");
} else {
console.log("Error: 目标URL响应失败");
}
capturedResponse = data['succ'] === 1 ? response : null;
await repeatXHR(100);
// 不要关闭浏览器
}
});

// 定期上下滑动
let scrollCount = 0; // 计数器
let scrollDirection = 1; // 1表示向下滑动,-1表示向上滑动

setInterval(async () => {
await page.evaluate((scrollDirection) => {
const windowHeight = window.innerHeight;
window.scrollBy(0, scrollDirection * windowHeight); // 向上或向下滑动一个屏幕高度
}, scrollDirection);

scrollCount++;

// 如果达到了五次滑动,切换方向并重置计数器
if (scrollCount === 5) {
scrollDirection *= -1; // 切换方向
scrollCount = 0; // 重置计数器
}
}, scrollInterval);


// 设置浏览器关闭定时器
setTimeout(async () => {
console.log("Success: 关闭浏览器");
await browser.close();
}, totalTime);
};

const repeatXHR = async (count) => {
if (!capturedResponse) {
console.log("Failed: 没有捕获到响应,无法重放");
return;
}
const request = capturedResponse.request();
for (let i = 0; i < count; i++) {
try {
const response = await axios({
method: request.method(),
url: request.url(),
headers: request.headers(),
params: request.params,
data: request.postData(),
});
if (response.data.succ !== 1) {
console.log(`Failed: 重放响应 ${i + 1}: 失败, succ!==1`);
return;
}
} catch (error) {
console.error(`Failed: 重放响应 ${i + 1}: 失败, ${error.message}`);
}
}
console.log(`Success: 重放响应 ${count} 次完毕`)
};

(async () => {
await getXHR();
})();

运行

代码会启动一个无头浏览器, 所以没有可视化也不需要担心。
个人测试24小时, 无任何问题, 使用的内存为300MB左右, CPU占用率为0.1%左右。
对了, 带上key参数是我接口的鉴权, 也就是上一篇文章的参数(个人有所修改)。
你实现了上一篇文章的获取可以使用你的接口。保证cookie是有效的即可。

1
2
3
4
5
6
7
8
9
10
node wxread.js key=xxxx

# 成功运行大概输出如下
# Success: 启动 Playwright 浏览器
# Success: 打开内容页面
# Success: 目标URL响应成功
# Success: 重放响应 100 次完毕
# Success: 目标URL响应成功
# Success: 重放响应 100 次完毕
# Success: 浏览器关闭 (400秒后)

本站由 钟意 使用 Stellar 1.28.1 主题创建。
又拍云 提供CDN加速/云存储服务
vercel 提供托管服务
湘ICP备2023019799号-1
总访问 次 | 本页访问