You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改Chrome扩展中的injectScript函数以注入Brython代码?

如何修改injectScript函数以注入Brython代码?

我明白你现在遇到的问题:用现有的injectScript能正常加载普通JS,但加载Brython代码时完全没反应,既不报错也不执行。这其实是因为Brython的执行逻辑和普通JS不一样,咱们一步步来解决:

问题根源

  1. Brython不会自动处理动态添加的Python脚本:Brython默认只会在页面初始加载时扫描一次带有text/python类型的脚本标签,之后动态添加的标签不会被自动解析执行。
  2. 版本不兼容风险:你加载的brython.min.js是3.8.9版本,但brython_stdlib.min.js是3.9.5版本,版本不一致可能导致隐藏问题。
  3. 缺少Brython初始化步骤:加载Brython核心库后,需要主动调用brython()完成初始化,否则后续的Python代码无法被解析。

解决方案一:修改现有injectScript支持Brython脚本

我们可以给原函数加个参数,标记是否为Python脚本,加载完成后主动调用Brython的API执行它:

function injectScript(src, isPython = false){
  return new Promise((resolve, reject) => {
    const script = document.createElement('script');
    script.src = src;
    // 为Python脚本设置正确的type属性
    script.setAttribute('type', isPython ? 'text/python' : 'text/javascript');
    
    script.addEventListener('load', async () => {
      if (isPython) {
        try {
          // 主动获取脚本内容并通过Brython API执行
          const code = await (await fetch(src)).text();
          brython_run_script(code);
          resolve();
        } catch (err) {
          reject(err);
        }
      } else {
        resolve();
      }
    });
    script.addEventListener('error', e => reject(e.error));
    document.head.appendChild(script);
  });
}

然后调整调用逻辑,确保初始化Brython并使用相同版本的核心库和stdlib:

// 统一使用3.9.5版本,避免兼容问题
injectScript("https://cdnjs.cloudflare.com/ajax/libs/brython/3.9.5/brython.min.js")
  .then(() => {
    console.log('Brython核心库加载完成!');
    // 初始化Brython,开启debug模式方便排查问题
    brython({debug: 1});
    return injectScript("https://cdnjs.cloudflare.com/ajax/libs/brython/3.9.5/brython_stdlib.min.js");
  })
  .then(() => {
    console.log('Brython标准库加载完成!');
    // 注入Python脚本,标记isPython为true
    return injectScript(chrome.runtime.getURL("/python.js"), true);
  })
  .then(() => {
    console.log("Python代码执行完成!")
  })
  .catch(error => {
    console.error('加载/执行出错:', error);
  });

解决方案二:专门编写injectPython函数(更简洁可靠)

如果不需要复用原函数,直接写一个专门加载执行Python代码的函数会更清晰:

function injectPython(src){
  return fetch(src)
    .then(res => {
      if (!res.ok) throw new Error(`加载脚本失败: ${res.status}`);
      return res.text();
    })
    .then(code => {
      // 直接调用Brython的API执行代码
      brython_run_script(code);
      return Promise.resolve();
    })
    .catch(err => Promise.reject(err));
}

调用方式和上面类似,确保先初始化Brython:

injectScript("https://cdnjs.cloudflare.com/ajax/libs/brython/3.9.5/brython.min.js")
  .then(() => {
    console.log('Brython核心库加载完成!');
    brython({debug: 1});
    return injectScript("https://cdnjs.cloudflare.com/ajax/libs/brython/3.9.5/brython_stdlib.min.js");
  })
  .then(() => {
    console.log('Brython标准库加载完成!');
    return injectPython(chrome.runtime.getURL("/python.js"));
  })
  .then(() => {
    console.log("Python代码执行完成!")
  })
  .catch(error => {
    console.error('加载/执行出错:', error);
  });

额外注意事项

  1. 确保页面存在目标元素:你的Python代码里绑定了document['mybutton'],要确保页面上确实存在id为mybutton的按钮,否则会报错。可以给Python代码加个容错处理:
    from browser import document, alert
    import traceback
    
    def hello():
        alert("hello world")
    
    try:
        if 'mybutton' in document:
            document['mybutton'].bind('click', hello)
        else:
            print("未找到id为mybutton的元素")
    except Exception as e:
        traceback.print_exc()
    
  2. debug模式排查:初始化Brython时开启debug:1,可以在控制台看到详细的执行日志,方便定位问题。

内容的提问来源于stack exchange,提问作者w1nter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 10:59:09