如何在Node.js项目中运行Python脚本并解决依赖缺失问题
问题:Node.js调用Python爬虫脚本缺少依赖库的解决办法
需求与问题
我需要实现两个GET接口/servers和/items,均返回JSON数据:
/items直接返回本地itemsList.json文件/servers需要运行Python爬虫脚本serverScrapper.py抓取数据生成serversList.json后返回
目前脚本无法运行,报错提示缺少bs4、requests依赖库,不清楚如何让Node.js自动处理Python依赖的安装,仅将Python脚本复制到了项目目录中。
现有server.js代码
const app = require('express')(); const { dirname } = require('path'); const appDir = dirname(require.main.filename); const fs = require('fs'); const { exec } = require('child_process'); const { PythonShell } = require('python-shell'); const PORT = 8080; const options = { pythonPath: process.env.PYTHONPATH }; app.get('/servers', (req, res) => { // Run the serversScrapper.py script and update the serversList.json file PythonShell.run(`${appDir}/serverScrapper.py`, options, (err, results) => { if (err) { console.error(err); res.sendStatus(500); return; } // Send the updated serversList.json file as the response res.sendFile(`${appDir}/serversList.json`, (err) => { if (err) { res.status(500).send(err); } }); }); }); app.get('/items', (req, res) => { res.sendFile(`${appDir}/itemsList.json`, (err) => { if (err) { res.status(500).send(err); } }); }); // Run the script every 2 minutes setInterval(() => { PythonShell.run(`${appDir}/serverScrapper.py`, null, (err, results) => { if (err) { console.error(err); } }); }, 2 * 60 * 1000); app.listen(PORT, () => console.log('Server up at 8000'))
错误日志
PythonShellError: ModuleNotFoundError: No module named 'bs4' at PythonShell.parseError (/rbd/pnpm-volume/eb08c55a-3afc-4775-99f3-8543de0493fc/node_modules/python-shell/index.js:295:21) at terminateIfNeeded (/rbd/pnpm-volume/eb08c55a-3afc-4775-99f3-8543de0493fc/node_modules/python-shell/index.js:190:32) at ChildProcess.<anonymous> (/rbd/pnpm-volume/eb08c55a-3afc-4775-99f3-8543de0493fc/node_modules/python-shell/index.js:182:13) at ChildProcess.emit (events.js:400:28) at Process.ChildProcess._handle.onexit (internal/child_process.js:282:12) ----- Python Traceback ----- File "/app/serverScrapper.py", line 2, in <module> from bs4 import BeautifulSoup { traceback: 'Traceback (most recent call last):\n' + ' File "/app/serverScrapper.py", line 2, in <module>\n' + ' from bs4 import BeautifulSoup\n' + "ModuleNotFoundError: No module named 'bs4'\n", executable: 'python3', options: null, script: '/app/serverScrapper.py', args: null, exitCode: 1 }
解决方案
1. 定义Python依赖清单
在项目根目录创建requirements.txt文件,写入需要的依赖(json是Python标准库,无需安装):
beautifulsoup4 requests
2. 修改Node.js代码,自动安装Python依赖
在server.js中添加自动安装依赖的逻辑,确保启动服务时先安装好Python依赖:
// 启动时自动安装Python依赖 exec('pip install -r requirements.txt', (err, stdout, stderr) => { if (err) { console.error('Python依赖安装失败:', stderr); return; } console.log('Python依赖安装完成:', stdout); });
3. 修正脚本调用的配置问题
- 把
setInterval中的PythonShell.run第二个参数从null改为options,确保使用统一的Python环境:setInterval(() => { PythonShell.run(`${appDir}/serverScrapper.py`, options, (err, results) => { if (err) { console.error(err); } }); }, 2 * 60 * 1000); - 修正端口日志的错误,把
console.log('Server up at 8000')改为console.log(Server up at ${PORT}),避免端口号混淆。
4. 可选:使用虚拟环境(推荐)
如果担心全局依赖冲突,可以创建Python虚拟环境:
- 在项目根目录执行:
python3 -m venv venv - 修改
options中的pythonPath为虚拟环境的Python路径:const options = { pythonPath: `${appDir}/venv/bin/python3` // Windows环境改为venv/Scripts/python.exe }; - 同时修改安装依赖的命令为虚拟环境的pip:
exec(`${appDir}/venv/bin/pip install -r requirements.txt`, (err, stdout, stderr) => { // ... 逻辑不变 });
内容的提问来源于stack exchange,提问作者Cuyer
相关产品推荐
相关产品推荐

