Node.js中使用Puppeteer调用Python解决验证码的报错问题
问题解决步骤
1. 优先修复Python侧运行错误
- 版本适配:你用到的hcapbypass库使用了Python函数返回值类型注解语法,必须使用Python 3.6及以上版本运行。你之前的低版本Python触发的
-> str语法错误就是版本过低导致的,直接使用你安装的Python 3.10版本即可。 - 补全bypass函数参数:从报错
TypeError: bypass() missing 1 required positional argument: 's'可知,你当前调用的bypass函数参数数量不符。请查看本地hcapbypass.py文件中bypass函数的定义,按声明的参数顺序补全缺失的入参,常见的该类函数需要传入sitekey、站点域名、代理配置、User-Agent四个参数,补全对应参数即可,示例修改后的bypass.py:
from hcapbypass import bypass import sys # 按你本地bypass函数要求补全第四个参数,这里示例传入User-Agent captcha_solved = bypass(sys.argv[1], 'google.com', True, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36') print(captcha_solved)
- 先在命令行验证Python脚本可正常运行:执行
python3 /MY_PATH/backend/bypass/bypass.py 你的sitekey,确认可以正常输出验证码结果后再处理Node.js侧的调用问题。
2. 修复python-shell调用的错误
- 路径配置错误:你已经在options中配置了
scriptPath: path.resolve('bypass'),PythonShell.run的第一个参数直接传bypass.py即可,不需要再加bypass/前缀,否则会导致路径拼接错误,找不到脚本文件。 - 回调参数解构错误:你之前的代码在python脚本执行报错时,回调的第二个返回值为null,直接解构会触发迭代错误,需要先判断err后再处理返回值。
- Python路径配置错误:将
pythonPath改为你Python3.10的实际路径,比如/usr/bin/python3或者你的安装路径,避免调用到低版本Python。
修改后的python-shell调用代码示例:
let options = { mode: 'text', args: [captchas[0].sitekey], scriptPath: path.resolve('bypass'), pythonPath: '/usr/bin/python3', // 改为你Python3.10的实际路径 } console.log(`options.scriptPath`, options.scriptPath) PythonShell.run( `bypass.py`, // 修正路径 options, (err, results) => { if (err) { reject(err) // 先抛出错误不要直接解构 return } const captchaKey = results[1] ?? results[0] // 按实际输出的结果位置取值 let solutions = [ { _vendor: captchas[0]._vendor, id: captchas[0].id, text: captchaKey, hasSolution: true, }, ] resolve({ solutions }) } )
3. 若使用spawn调用的修复方案
- 调用python时使用正确的命令:如果你的系统中python指向低版本,就改为
python3作为spawn的第一个参数。 - 正确处理stdout输出:data事件返回的是Buffer对象,需要先转为字符串再处理,同时监听stderr输出排查错误。
修改后的spawn调用代码示例:
const location = path.resolve('bypass/bypass.py') console.log(`python3 ${location} ${captchas[0].sitekey}`) const run = spawn('python3', [location, captchas[0].sitekey]) // 改为python3 let output = '' // 收集stdout输出 run.stdout.on('data', (data) => { output += data.toString() }) // 监听错误输出 run.stderr.on('data', (err) => { console.error('Python执行错误:', err.toString()) reject(err) }) // 进程退出后处理结果 run.on('close', (code) => { if (code === 0) { // 按实际输出格式取验证码key,这里示例取输出的非空行 const captchaKey = output.trim().split('\n').pop() let solutions = [ { _vendor: captchas[0]._vendor, id: captchas[0].id, text: captchaKey, hasSolution: true, }, ] resolve({ solutions }) } else { reject(new Error(`Python脚本退出码: ${code}`)) } })
内容的提问来源于stack exchange,提问作者Aviv Ben Shahar
相关产品推荐
相关产品推荐

