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的Flask框架来构建一个简单的数字商品支付解决方案
Mar 31 Python
理解Python垃圾回收机制
Feb 12 Python
Python使用回溯法子集树模板获取最长公共子序列(LCS)的方法
Sep 08 Python
python实现m3u8格式转换为mp4视频格式
Feb 28 Python
python实现给scatter设置颜色渐变条colorbar的方法
Dec 13 Python
在Python中append以及extend返回None的例子
Jul 20 Python
Python图片的横坐标汉字实例
Dec 04 Python
Pytorch学习之torch用法----比较操作(Comparison Ops)
Jun 28 Python
Django实现内容缓存实例方法
Jun 30 Python
基于python的opencv图像处理实现对斑马线的检测示例
Nov 29 Python
Python 如何安装Selenium
May 06 Python
python标准库ElementTree处理xml
May 20 Python
Python WSGI 规范简介
使用pytorch实现线性回归
pytorch实现线性回归以及多元回归
python如何获取网络数据
Apr 11 #Python
Pytorch 使用tensor特定条件判断索引
selenium.webdriver中add_argument方法常用参数表
Apr 08 #Python
python3使用diagrams绘制架构图的步骤
You might like
Fine Uploader文件上传组件应用介绍
2013/01/06 PHP
PHP实现AES256加密算法实例
2014/09/22 PHP
PHP网站建设的流程与步骤分享
2015/09/25 PHP
PHP实现的分解质因数操作示例
2018/08/01 PHP
PHP下载大文件失败并限制下载速度的实例代码
2019/05/10 PHP
PHP检测一个数组有没有定义的方法步骤
2019/07/20 PHP
php多进程应用场景实例详解
2019/07/22 PHP
ext jquery 简单比较
2010/04/07 Javascript
jquery 新浪网易的评论块制作
2010/07/01 Javascript
ExtJS自定义主题(theme)样式详解
2013/11/18 Javascript
浅谈Vue 初始化性能优化
2017/08/31 Javascript
Angularjs Ng_repeat中实现复选框选中并显示不同的样式方法
2018/09/12 Javascript
Angular6 发送手机验证码按钮倒计时效果实现方法
2019/01/08 Javascript
js常用正则表达式集锦
2019/05/17 Javascript
微信小程序判断用户是否需要再次授权获取个人信息
2019/07/18 Javascript
vue实现下拉菜单树
2020/10/22 Javascript
[02:41]DOTA2亚洲邀请赛小组赛第三日 赛事回顾
2015/02/01 DOTA
[13:38]2015国际邀请赛中国战队出征仪式
2015/05/29 DOTA
[03:49]辉夜杯现场龙骑士COSER秀情商“我喜欢芬队!”
2015/12/27 DOTA
深入解析Python中的集合类型操作符
2015/08/19 Python
在阿里云服务器上配置CentOS+Nginx+Python+Flask环境
2016/06/18 Python
python3.4控制用户输入与输出的方法
2018/10/17 Python
Python使用进程Process模块管理资源
2020/03/05 Python
python如何处理程序无法打开
2020/06/16 Python
Laura官网:加拿大女性的顶级时尚目的地
2019/09/20 全球购物
Java编程面试题
2016/04/04 面试题
英文简历中的自我评价
2013/10/06 职场文书
英语文学专业学生的自我评价
2013/10/31 职场文书
开学寄语大全
2014/04/08 职场文书
社区维稳工作方案
2014/06/06 职场文书
课外活动实习计划
2015/01/19 职场文书
冬季作息时间调整通知
2015/04/24 职场文书
上课讲话检讨书范文
2015/05/07 职场文书
党支部审查意见
2015/06/02 职场文书
2015年音乐教研组工作总结
2015/07/22 职场文书
好段摘抄大全(48句)
2019/08/08 职场文书