python 调用js的四种方式


Posted in Python onApril 11, 2021

1. 前言

日常 Web 端爬虫过程中,经常会遇到参数被加密的场景,因此,我们需要分析网页源代码

通过调式,一层层剥离出关键的 JS 代码,使用 Python 去执行这段代码,得出参数加密前后的 Python 实现

本文将聊聊利用 Python 调用 JS 的4种方式

2. 准备

以一段简单的 JS 脚本为例,将代码写入到文件中

//norm.js
//计算两个数的和
function add(num1, num2) {
    return num1 + num2;
}

其中,定义了一个方法,计算两个数的和

3. 方式一:PyExecJS

PyExecJS 是使用最多的一种方式,底层实现方式是:在本地 JS 环境下运行 JS 代码
支持的 JS 环境包含:Node.js、PyV8、PhantomJS、Nashorn 等
首先,我们需要安装依赖包 PyExecJS

//py_exec_js_demo.py

//安装依赖
pip3 install PyExecJS

然后,从 JS 文件中读取源码

def js_from_file(file_name):
    """
    读取js文件
    :return:
    """
    with open(file_name, 'r', encoding='UTF-8') as file:
        result = file.read()

    return result

最后,使用 execjs 类的compile()方法编译加载上面的 JS 字符串,返回一个上下文对象

import execjs

from js_code import *

# 编译加载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 代码

首先,安装依赖库

# 安装依赖库
pip3 install js2py

然后使用 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 ,方便内部函数被调用

//计算两个数的和
function add(num1, num2) {
    return num1 + 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 环境,运行速度很快

import PyV8
from js_code import js_from_file

with PyV8.JSContext() as ctx:
    ctx.eval(js_from_file('./norm.js'))

# 调用js函数,指定参数
ctx.locals.add(1, 2)

更多功能可以参考:

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

7. 最后

上面总结了 Python 调用 JS 的 4 种方式

实际爬虫项目中,一般会先使用 node 命令进行一次测试,确保没问题后,再使用前 3 种方式的任意一种进行 Python 改写

示例代码地址:https://github.com/xingag/tools_python/tree/master/Python%E6%89%A7%E8%A1%8CJS%E6%80%BB%E7%BB%93

以上就是python 调用js的四种方式的详细内容,更多关于python 调用js的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
一张图带我们入门Python基础教程
Feb 05 Python
python selenium UI自动化解决验证码的4种方法
Jan 05 Python
Python实现全排列的打印
Aug 18 Python
Python用5行代码写一个自定义简单二维码
Oct 21 Python
python 将list转成字符串,中间用符号分隔的方法
Oct 23 Python
Python 实现数据结构中的的栈队列
May 16 Python
Python+Pyqt实现简单GUI电子时钟
Feb 22 Python
如何在 Django 模板中输出 "{{"
Jan 24 Python
python如何设置静态变量
Sep 07 Python
python 获取字典键值对的实现
Nov 12 Python
如何用Django处理gzip数据流
Jan 29 Python
python数字图像处理:图像的绘制
Jun 28 Python
Python WSGI 规范简介
使用pytorch实现线性回归
pytorch实现线性回归以及多元回归
python如何获取网络数据
Apr 11 #Python
Pytorch 使用tensor特定条件判断索引
selenium.webdriver中add_argument方法常用参数表
Apr 08 #Python
python3使用diagrams绘制架构图的步骤
You might like
模拟OICQ的实现思路和核心程序(三)
2006/10/09 PHP
Linux下实现PHP多进程的方法分享
2012/08/16 PHP
PHP实现动态删除XML数据的方法示例
2018/03/30 PHP
laravel 查询数据库获取结果实现判断是否为空
2019/10/24 PHP
JS 文字符串转换unicode编码函数
2009/05/30 Javascript
让FireFox支持innerText的实现代码
2009/12/01 Javascript
JS 密码强度验证(兼容IE,火狐,谷歌)
2010/03/15 Javascript
extjs grid设置某列背景颜色和字体颜色的方法
2010/09/03 Javascript
Javascript在IE和FireFox中的不同表现简析
2012/12/03 Javascript
JQuery中根据属性或属性值获得元素(6种情况获取方法)
2013/01/17 Javascript
JS的document.all函数使用示例
2013/12/30 Javascript
js读取被点击次数的简单实例(从数据库中读取)
2014/03/07 Javascript
学习JavaScript设计模式(继承)
2015/11/26 Javascript
JS实现兼容各种浏览器的获取选择文本的方法【测试可用】
2016/06/21 Javascript
vue.js入门教程之计算属性
2016/09/01 Javascript
JavaScript 闭包机制详解及实例代码
2016/10/10 Javascript
微信小程序中实现一对多发消息详解及实例代码
2017/02/14 Javascript
JavaScript函数节流和函数防抖之间的区别
2017/02/15 Javascript
Vue computed计算属性的使用方法
2017/07/14 Javascript
vue.js如何将echarts封装为组件一键使用详解
2017/10/10 Javascript
JS实现的简单表单验证功能示例
2017/10/13 Javascript
Vue+Element实现动态生成新表单并添加验证功能
2019/05/23 Javascript
websocket4.0+typescript 实现热更新的方法
2019/08/14 Javascript
Vue打包后访问静态资源路径问题
2019/11/08 Javascript
JavaScript检测是否开启了控制台(F12调试工具)
2020/10/02 Javascript
[01:48]DOTA2 2015国际邀请赛中国区预选赛第二日战报
2015/05/27 DOTA
Python+selenium 获取浏览器窗口坐标、句柄的方法
2018/10/14 Python
python创造虚拟环境方法总结
2019/03/04 Python
PyCharm 2020.2 安装详细教程
2020/09/25 Python
Ubuntu20下的Django安装的方法步骤
2021/01/24 Python
html5定制表单_动力节点Java学院整理
2017/07/11 HTML / CSS
十佳教师事迹材料
2014/01/11 职场文书
公民代理授权委托书
2014/09/24 职场文书
2014年民政工作总结
2014/11/26 职场文书
天下第一关导游词
2015/02/06 职场文书
Python - 10行代码集2000张美女图
2021/05/23 Python