1. 程式人生 > 實用技巧 >最全總結!聊聊 Python 呼叫 JS 的幾種方式

最全總結!聊聊 Python 呼叫 JS 的幾種方式

1. 前言

很多人學習python,不知道從何學起。
很多人學習python,掌握了基本語法過後,不知道在哪裡尋找案例上手。
很多已經做案例的人,卻不知道如何去學習更加高深的知識。
那麼針對這三類人,我給大家提供一個好的學習平臺,免費領取視訊教程,電子書籍,以及課程的原始碼!
QQ群:1097524789

日常 Web 端爬蟲過程中,經常會遇到引數被加密的場景,因此,我們需要分析網頁原始碼

通過調式,一層層剝離出關鍵的 JS 程式碼,使用 Python 去執行這段程式碼,得出引數加密前後的Python實現

本文將聊聊利用Python 呼叫 JS 的4種方式

2. 準備

以一段簡單的JS 指令碼為例,將程式碼寫入到檔案中

//norm.js
//計算兩個數的和
functionadd(num1,num2){
returnnum1+num2;
}

其中,定義了一個方法,計算兩個數的和

3. 方式一:PyExecJS

PyExecJS 是使用最多的一種方式,底層實現方式是:在本地 JS 環境下執行 JS 程式碼

支援的 JS 環境包含:Node.js、PyV8、PhantomJS、Nashorn 等

首先,我們需要安裝依賴包PyExecJS

//py_exec_js_demo.py

//安裝依賴
pip3installPyExecJS

然後,從 JS 檔案中讀取原始碼

defjs_from_file(file_name):
"""
讀取js檔案
:return:
"""
withopen(file_name,'r',encoding='UTF-8')asfile:
result=file.read()

returnresult

最後,使用 execjs 類的compile()方法編譯載入上面的 JS 字串,返回一個上下文物件

importexecjs

fromjs_codeimport*

#編譯載入js字串
context1=execjs.compile(js_from_file('./norm.js'))

最後,呼叫上下文物件的call()方法執行 JS 方法

其中,引數包含:JS 程式碼被調的方法名、對應方法的傳入引數

#呼叫js程式碼中的add()方法,引數為2和3
#方法名:add
#引數:2和3
result1=context1.call("add",2,3)

print(result1)

需要注意的,由於PyExecJS執行在本地 JS 環境下,使用之前會啟動 JS 環境,最終導致執行速度會偏慢

更多功能可以參考:

https://github.com/doloopwhile/PyExecJS

4. 方式二:js2py

js2py作為一個純 Python 實現的 JS 直譯器,可以完全脫離 JS 環境,直接將 JS 程式碼轉換為 Python 程式碼

首先,安裝依賴庫

#安裝依賴庫
pip3installjs2py

然後使用 js2py 中的EvalJs()方法生成一個上下文物件

#使用獲取上下js2py生成一個上下文環境
context=js2py.EvalJs()

接著利用上下文物件執行 JS 指令碼,轉換為Python 程式碼

#執行整段JS程式碼
context.execute(js_content)

最後,利用上下文呼叫 JS 中的方法,並制定輸入引數即可

#使用上下文context呼叫具體的函式
#函式名:add
#引數:1,2
result=context.add(1,2)
print(result)

需要注意是,如果 JS 是很長的混淆程式碼,轉換為 Python 的過程可能會報錯

更多功能可以參考:

https://github.com/PiotrDabkowski/Js2Py

5. 方式三:Node.js

實際上是使用 Python 的os.popen執行 node 命令,執行 JS 指令碼

首先,確保本地已經安裝了 Node.js 環境

修改 JS 指令碼,新增一個匯出函式 init ,方便內部函式被呼叫

//計算兩個數的和
functionadd(num1,num2){
returnnum1+num2;
}

//新增一個匯出函式(node方式)
module.exports.init=function(arg1,arg2){
//呼叫函式,並返回
console.log(add(arg1,arg2));
};

然後,將呼叫 JS方法的命令組成一個字串

#組成呼叫js的命令
# node命令:node -e
cmd='node-e"require(\\"%s\\").init(%s,%s)"'%('./norm',3,5)

最後,通過 os.popen 執行命令即可

pipeline=os.popen(cmd)

#讀取結果
result=pipeline.read()

print('結果是:',result)

6. 方式四:PyV8

PyV8 是 Google將 Chrome V8引擎用 Python 封裝的依賴庫

它不依賴本地 JS 環境,執行速度很快

importPyV8
fromjs_codeimportjs_from_file

withPyV8.JSContext()asctx:
ctx.eval(js_from_file('./norm.js'))

#呼叫js函式,指定引數
ctx.locals.add(1,2)

但是經過反覆測試發現,MAC 和 PC 在 Python3 環境下,使用 PyV8 會報各種奇怪的問題,所以不推薦使用!

更多功能可以參考:

https://github.com/emmetio/pyv8-binaries

7. 最後

上面總結了 Python 呼叫 JS 的 4 種方式

實際爬蟲專案中,一般會先使用 node 命令進行一次測試,確保沒問題後,再使用前 3 種方式的任意一種進行 Python 改寫。