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

如何在HTML加载完成后多次调用Pyodide函数执行文本词干提取

问题根源
  • 重复初始化冲突:原有main函数每次调用都会重新加载Pyodide环境、重复安装snowballstemmer依赖,异步加载的执行顺序混乱会直接导致后续调用失效
  • DOM获取时机错误:没有等页面元素完全渲染就执行元素获取逻辑,会拿到空值导致处理失败
  • 能力没有复用:原有词干提取逻辑耦合在单次初始化流程里,没有封装为可独立调用的方法,无法灵活处理多个文本、表格行等场景
修复后的完整实现
<body>
  <script src="https://cdn.jsdelivr.net/pyodide/dev/full/pyodide.js"></script>
  
  <!-- 示例表格,供逐行处理 -->
  <table id="targetTable" border="1">
    <tr><td>Hello world this is a test row</td></tr>
    <tr><td>JavaScript and Python integration example</td></tr>
    <tr><td>Stemming each row of the table</td></tr>
  </table>
  <div id="origen">This text is inside of HTML element</div>

  <script type="text/javascript">
    // 全局保存pyodide实例,避免重复初始化
    let pyodideInstance = null;

    // 初始化Pyodide和依赖,只执行一次
    async function initPyodide() {
      if (pyodideInstance) return pyodideInstance;
      
      const pyodide = await loadPyodide({
        indexURL: "https://cdn.jsdelivr.net/pyodide/dev/full/",
      });
      await pyodide.loadPackage("micropip");
      await pyodide.runPythonAsync(`
        import micropip
        await micropip.install('snowballstemmer')
        import snowballstemmer
        stemmer = snowballstemmer.stemmer('english')
      `);
      pyodideInstance = pyodide;
      return pyodideInstance;
    }

    // 封装可复用的词干提取方法
    async function stemText(text) {
      const pyodide = await initPyodide();
      pyodide.globals.set("inputText", text);
      return pyodide.runPython(`
        stemmer.stemWords(inputText.split())
      `).toJs();
    }

    // 等DOM完全加载后执行所有处理逻辑
    document.addEventListener('DOMContentLoaded', async () => {
      // 先初始化Pyodide
      await initPyodide();

      // 示例1:处理表格每一行
      const table = document.getElementById('targetTable');
      const rows = table.querySelectorAll('tr');
      for (let i = 0; i < rows.length; i++) {
        const rowText = rows[i].textContent.trim();
        const stemResult = await stemText(rowText);
        // 这里可以根据需求修改,比如新增列放结果
        const newCell = rows[i].insertCell();
        newCell.textContent = JSON.stringify(stemResult);
        console.log(`表格第${i+1}行处理结果:`, stemResult);
      }

      // 示例2:处理固定元素文本
      const origenText = document.getElementById('origen').textContent;
      const origenStem = await stemText(origenText);
      console.log('origen元素处理结果:', origenStem);

      // 示例3:绑定点击事件
      document.getElementById('origen').onclick = async function() {
        const clickResult = await stemText('触发点击时的测试文本');
        console.log('点击处理结果:', clickResult);
      }

      // 自定义文本处理
      const myNewkwStemm = await stemText('other word');
      const myNewkwStemm2 = await stemText('word2');
      console.log('自定义文本1结果:', myNewkwStemm);
      console.log('自定义文本2结果:', myNewkwStemm2);
    });
  </script>
</body>
关键说明
  • Pyodide全局仅初始化一次,避免重复加载的资源浪费和冲突问题
  • 所有DOM相关操作都放在DOMContentLoaded事件回调中,确保页面元素完全渲染后再执行处理
  • 封装了独立的stemText异步方法,传入任意文本即可返回词干提取结果,可灵活适配表格遍历、点击事件触发、批量文本处理等各类需求
  • 示例中包含表格逐行处理的完整逻辑,处理后的结果可以根据需求写回原表格、输出到控制台或插入到页面任意位置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 19:06:02