Skip to content

建议可以集成直接调用相关目标网页内容的js #20

@liudonghua123

Description

@liudonghua123

我使用元宝问了一个问题:是否可以使用 playwright 、puppeteer 等类似工具,提供一个 web 服务调用网页中的一个js函数,例如 网页中提供了一个 encrypt(plain_text), 需要提供一个 http://localhost:123/encrypt?payload=plain_text 端口处理plain_text, 直接返回加密后的内容即可

以下是他的回答,可以参考一下




是的,完全可以使用 PlaywrightPuppeteer 这类浏览器自动化工具搭建一个 Web 服务,通过 HTTP 接口调用网页中的 JavaScript 函数(如 encrypt(plain_text)),并返回加密结果。以下是具体实现方案和步骤:


🛠️ 核心思路

  1. 启动无头浏览器:通过 Playwright/Puppeteer 控制浏览器加载目标网页。
  2. 注入或调用 JS 函数:利用 page.evaluate() 执行网页中的加密函数。
  3. 封装为 HTTP 服务:使用 Express 等框架创建 API 接口,接收参数并返回加密结果。

🔧 实现步骤(以 Playwright + Node.js 为例)

1. 环境准备

安装依赖:

npm install playwright express

2. 搭建 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();
});

⚙️ 关键代码解析

  1. page.evaluate()

    • 这是核心方法,用于在浏览器上下文中执行 JS 函数,并返回结果。
    • 示例:page.evaluate((text) => window.encrypt(text), payload) 调用网页中的 encrypt 函数。
  2. 浏览器初始化

    • 启动时加载目标网页(需包含 encrypt 函数),后续所有请求复用同一个 page 实例,避免重复加载网页的开销。
  3. HTTP 接口设计

    • 通过 GET /encrypt?payload=xxx 接收明文,返回加密结果。
    • 错误处理:校验参数缺失、捕获执行异常(如函数未定义)。

⚠️ 注意事项

  1. 网页加载可靠性

    • 确保目标网页完全加载后再调用函数(使用 page.waitForFunction(() => window.encrypt) 检测函数是否就绪)。
    • 若网页有反爬机制(如 Cloudflare),需额外处理验证码或 Cookie。
  2. 性能优化

    • 复用浏览器实例:避免每次请求都启动新浏览器(耗时 1~2 秒)。
    • 并发限制:通过任务队列(如 p-limit)控制并发调用,防止浏览器过载。
  3. 安全风险

    • 限制接口访问 IP,避免公开暴露。
    • 验证输入内容,防止 XSS 攻击(如 payload 包含恶意代码)。
  4. 替代方案: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#rdhttps://blog.csdn.net/seanyang_/article/details/132252965 中进一步参考。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions