-
Notifications
You must be signed in to change notification settings - Fork 125
Description
我使用元宝问了一个问题:是否可以使用 playwright 、puppeteer 等类似工具,提供一个 web 服务调用网页中的一个js函数,例如 网页中提供了一个 encrypt(plain_text), 需要提供一个 http://localhost:123/encrypt?payload=plain_text 端口处理plain_text, 直接返回加密后的内容即可
以下是他的回答,可以参考一下
是的,完全可以使用 Playwright 或 Puppeteer 这类浏览器自动化工具搭建一个 Web 服务,通过 HTTP 接口调用网页中的 JavaScript 函数(如 encrypt(plain_text)),并返回加密结果。以下是具体实现方案和步骤:
🛠️ 核心思路
- 启动无头浏览器:通过 Playwright/Puppeteer 控制浏览器加载目标网页。
- 注入或调用 JS 函数:利用
page.evaluate()执行网页中的加密函数。 - 封装为 HTTP 服务:使用 Express 等框架创建 API 接口,接收参数并返回加密结果。
🔧 实现步骤(以 Playwright + Node.js 为例)
1. 环境准备
安装依赖:
npm install playwright express2. 搭建 HTTP 服务
const express = require('express');
const { chromium } = require('playwright'); // 或 puppeteer
const app = express();
const PORT = 123;
let browser, page;
// 初始化浏览器实例
async function initBrowser() {
browser = await chromium.launch({ headless: true }); // 无头模式
const context = await browser.newContext();
page = await context.newPage();
await page.goto('https://目标网站.com'); // 包含 encrypt 函数的页面
}
// 调用网页中的 encrypt 函数
async function callEncrypt(payload) {
return page.evaluate((text) => {
return window.encrypt(text); // 直接调用网页全局函数
}, payload);
}
// 创建 API 接口
app.get('/encrypt', async (req, res) => {
const payload = req.query.payload;
if (!payload) return res.status(400).send('缺少 payload 参数');
try {
const encrypted = await callEncrypt(payload);
res.send(encrypted); // 返回加密结果
} catch (error) {
res.status(500).send('加密失败: ' + error.message);
}
});
// 启动服务
initBrowser().then(() => {
app.listen(PORT, () => console.log(`服务运行在 http://localhost:${PORT}/encrypt`));
});
// 优雅关闭浏览器
process.on('SIGINT', async () => {
await browser.close();
process.exit();
});⚙️ 关键代码解析
-
page.evaluate()- 这是核心方法,用于在浏览器上下文中执行 JS 函数,并返回结果。
- 示例:
page.evaluate((text) => window.encrypt(text), payload)调用网页中的encrypt函数。
-
浏览器初始化
- 启动时加载目标网页(需包含
encrypt函数),后续所有请求复用同一个page实例,避免重复加载网页的开销。
- 启动时加载目标网页(需包含
-
HTTP 接口设计
- 通过
GET /encrypt?payload=xxx接收明文,返回加密结果。 - 错误处理:校验参数缺失、捕获执行异常(如函数未定义)。
- 通过
⚠️ 注意事项
-
网页加载可靠性
- 确保目标网页完全加载后再调用函数(使用
page.waitForFunction(() => window.encrypt)检测函数是否就绪)。 - 若网页有反爬机制(如 Cloudflare),需额外处理验证码或 Cookie。
- 确保目标网页完全加载后再调用函数(使用
-
性能优化
- 复用浏览器实例:避免每次请求都启动新浏览器(耗时 1~2 秒)。
- 并发限制:通过任务队列(如
p-limit)控制并发调用,防止浏览器过载。
-
安全风险
- 限制接口访问 IP,避免公开暴露。
- 验证输入内容,防止 XSS 攻击(如
payload包含恶意代码)。
-
替代方案:Puppeteer
- 代码逻辑与 Playwright 类似,但 Playwright 对多浏览器(Chromium/Firefox/WebKit)支持更好。
🌰 实际应用案例
在 小红书逆向工程 中,通过 Playwright 调用页面全局函数 window.sign() 生成加密参数 x-s,再通过 Express 接口暴露给爬虫程序,完美绕过前端加密逻辑。
💎 总结
- ✅ 可行性强:Playwright/Puppeteer + Express 可快速搭建 JS 函数调用服务。
- ✅ 适用场景:需动态执行网页 JS 的加密、环境检测等操作。
⚠️ 注意事项:性能优化、反爬策略和安全性需重点考虑。
完整代码示例可在 http://mp.weixin.qq.com/s?__biz=MzU4MDY4ODU2MA==&mid=2247484293&idx=1&sn=de1dccfc24e2f69ccadf62ecb9de6ef1&chksm=fd524c5aca25c54c0fd10961d8e39b5d2a205530825fe51992615a3c802bacbb14e4bb9725b7#rd 和 https://blog.csdn.net/seanyang_/article/details/132252965 中进一步参考。