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解析模块(ConfigParser)使用方法
Dec 10 Python
python获取指定路径下所有指定后缀文件的方法
May 26 Python
Python中list查询及所需时间计算操作示例
Jun 21 Python
Python统计纯文本文件中英文单词出现个数的方法总结【测试可用】
Jul 25 Python
Python命名空间的本质和加载顺序
Dec 17 Python
Python调用scp向服务器上传文件示例
Dec 22 Python
Python实现aes加密解密多种方法解析
May 15 Python
Keras模型转成tensorflow的.pb操作
Jul 06 Python
PyCharm2019 安装和配置教程详解附激活码
Jul 31 Python
利用python绘制正态分布曲线
Jan 04 Python
Python线程池与GIL全局锁实现抽奖小案例
Apr 13 Python
Python绘制散乱的点构成的图的方法
Apr 21 Python
Python WSGI 规范简介
使用pytorch实现线性回归
pytorch实现线性回归以及多元回归
python如何获取网络数据
Apr 11 #Python
Pytorch 使用tensor特定条件判断索引
selenium.webdriver中add_argument方法常用参数表
Apr 08 #Python
python3使用diagrams绘制架构图的步骤
You might like
php中用文本文件做数据库的实现方法
2008/03/27 PHP
php浏览历史记录的方法
2015/03/10 PHP
CodeIgniter中使用Smarty3基本配置
2015/06/29 PHP
laravel-admin的多级联动方法
2019/09/30 PHP
input 高级限制级用法
2009/03/26 Javascript
jquery select操作的日期联动实现代码
2009/12/06 Javascript
JS调用页面表格导出excel示例代码
2014/03/18 Javascript
JQuery工具函数汇总
2015/06/15 Javascript
JS实现统计复选框选中个数并提示确定与取消的方法
2015/07/01 Javascript
JavaScript仿flash遮罩动画效果
2016/06/15 Javascript
JavaScript基于原型链的继承
2016/06/22 Javascript
Vue.js每天必学之指令系统与自定义指令
2016/09/07 Javascript
BootStrap表单控件之文本域textarea
2017/05/23 Javascript
JS实现数组去重方法总结(六种方法)
2017/07/14 Javascript
解决vue页面DOM操作不生效的问题
2018/03/17 Javascript
浅析vue给不同环境配置不同打包命令
2018/08/17 Javascript
微信小程序页面缩放式侧滑效果的实现代码
2018/11/15 Javascript
微信小程序出现wx.getLocation再次授权问题的解决方法分析
2019/01/16 Javascript
js中怎么判断两个字符串相等的实例
2019/01/17 Javascript
[38:54]完美世界DOTA2联赛PWL S2 Rebirth vs LBZS 第一场 11.28
2020/12/01 DOTA
python定时利用QQ邮件发送天气预报的实例
2017/11/17 Python
用Python将mysql数据导出成json的方法
2018/08/21 Python
如何使用Python脚本实现文件拷贝
2019/11/20 Python
CSS3 3D制作实战案例分析
2016/09/18 HTML / CSS
HTML5+CSS3绘制锯齿状的矩形
2016/03/01 HTML / CSS
周仰杰(JIMMY CHOO)英国官方网站:闻名世界的鞋子品牌
2018/10/28 全球购物
iHerb俄罗斯:维生素、补品和天然产品
2020/07/09 全球购物
家乐福台湾线上购物网:Carrefour台湾
2020/09/15 全球购物
捐资助学倡议书
2014/04/15 职场文书
厉行勤俭节约倡议书
2014/05/16 职场文书
中国梦口号
2014/06/13 职场文书
成品仓库管理员岗位职责
2015/04/09 职场文书
2015年银行个人工作总结
2015/05/14 职场文书
php 解析非标准json、非规范json
2021/04/01 PHP
Java spring单点登录系统
2021/09/04 Java/Android
微软Win11 全新照片应用面向 Dev预览版推出 新版本上手体验图集
2022/09/23 数码科技