execjs执行js报错, subprocess.py编码问题
文章目录
- 起因
- 报错
- 问题关键
- 两种解决办法
- 第一种,治标,不治本
- 第二种,治标,又治本
- Ctrl+F
- Create new Popen instance.
- utf-8
- OK
起因
import execjs # 导入# 生成JavaScript运行环境,环境名可以指定
node = execjs.get() # 安装nodejs后,会得到运行环境名为:Node.js (V8)
print(node)# JavaScript中表达式(字符串字面量, 数字字面量, 算术表达式)会自动返回其值
print(execjs.eval('"宇宙第一小趴菜"'))
# print(execjs.eval('3.14'))
# print(execjs.eval('18'))
# print(execjs.eval('3+5'))
报错
ExternalRuntime(Node.js (V8))
Exception in thread Thread-1:
Traceback (most recent call last):File "D:\miniconda3\envs\spider_base\lib\threading.py", line 980, in _bootstrap_innerself.run()File "D:\miniconda3\envs\spider_base\lib\threading.py", line 917, in runself._target(*self._args, **self._kwargs)File "D:\miniconda3\envs\spider_base\lib\subprocess.py", line 1495, in _readerthreadbuffer.append(fh.read())
UnicodeDecodeError: 'gbk' codec can't decode byte 0xac in position 16: illegal multibyte sequence
Traceback (most recent call last):File "D:\JsSpiderCode\02 常见加密算法\01 execjs使用.py", line 8, in <module>print(execjs.eval('"宇宙第一小趴菜"'))File "D:\miniconda3\envs\spider_base\lib\site-packages\execjs\__init__.py", line 51, in evalreturn get().eval(source, cwd)File "D:\miniconda3\envs\spider_base\lib\site-packages\execjs\_abstract_runtime.py", line 25, in evalreturn self.compile('', cwd=cwd).eval(source)File "D:\miniconda3\envs\spider_base\lib\site-packages\execjs\_abstract_runtime_context.py", line 27, in evalreturn self._eval(source)File "D:\miniconda3\envs\spider_base\lib\site-packages\execjs\_external_runtime.py", line 78, in _evalreturn self.exec_(code)File "D:\miniconda3\envs\spider_base\lib\site-packages\execjs\_abstract_runtime_context.py", line 18, in exec_return self._exec_(source)File "D:\miniconda3\envs\spider_base\lib\site-packages\execjs\_external_runtime.py", line 88, in _exec_return self._extract_result(output)File "D:\miniconda3\envs\spider_base\lib\site-packages\execjs\_external_runtime.py", line 156, in _extract_resultoutput = output.replace("\r\n", "\n").replace("\r", "\n")
AttributeError: 'NoneType' object has no attribute 'replace'
问题关键
默认情况下在使用pyexecjs指定编译的时候, 会引用subprocess.py, 此文件默认使用的编码是系统编码, 从而引发报错
两种解决办法
第一种,治标,不治本
在调用 import execjs之前修改 subprocess.py 编码为utf-8
import subprocess
from functools import partial# 重新定义 subprocess.Popen,设置默认编码为 utf-8
subprocess.Popen = partial(subprocess.Popen, encoding="utf-8")
import subprocess
from functools import partial# 重新定义 subprocess.Popen,设置默认编码为 utf-8
subprocess.Popen = partial(subprocess.Popen, encoding="utf-8")import execjs # 导入# 生成JavaScript运行环境,环境名可以指定
node = execjs.get() # 安装nodejs后,会得到运行环境名为:Node.js (V8)
print(node)# JavaScript中表达式(字符串字面量, 数字字面量, 算术表达式)会自动返回其值
print(execjs.eval('"宇宙第一小趴菜"'))
print(execjs.eval('3.14'))
print(execjs.eval('Boolean("True")'))
print(execjs.eval('18'))
print(execjs.eval('3+5'))
第二种,治标,又治本
进入到 subprocess.py
D:\miniconda3\envs\spider_base\lib\subprocess.py
Ctrl+F
Create new Popen instance.
"""Create new Popen instance."""
utf-8
OK
import execjs # 导入# 生成JavaScript运行环境,环境名可以指定
node = execjs.get() # 安装nodejs后,会得到运行环境名为:Node.js (V8)
print(node)# JavaScript中表达式(字符串字面量, 数字字面量, 算术表达式)会自动返回其值
print(execjs.eval('"宇宙第一小趴菜"'))
print(execjs.eval('3.14'))
print(execjs.eval('Boolean("True")'))
print(execjs.eval('18'))
print(execjs.eval('3+5'))