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中unittest模块做UT(单元测试)使用实例
Jun 12 Python
Python中运算符"=="和"is"的详解
Oct 08 Python
python爬虫入门教程--快速理解HTTP协议(一)
May 25 Python
Tensorflow 自带可视化Tensorboard使用方法(附项目代码)
Feb 10 Python
python中ASCII码字符与int之间的转换方法
Jul 09 Python
Python设计模式之抽象工厂模式原理与用法详解
Jan 15 Python
Python变量、数据类型、数据类型转换相关函数用法实例详解
Jan 09 Python
Python操作注册表详细步骤介绍
Feb 05 Python
pandas和spark dataframe互相转换实例详解
Feb 18 Python
Python如何实现爬取B站视频
May 20 Python
在keras中实现查看其训练loss值
Jun 16 Python
分享一枚pycharm激活码适用所有pycharm版本我的pycharm2020.2.3激活成功
Nov 20 Python
Python WSGI 规范简介
使用pytorch实现线性回归
pytorch实现线性回归以及多元回归
python如何获取网络数据
Apr 11 #Python
Pytorch 使用tensor特定条件判断索引
selenium.webdriver中add_argument方法常用参数表
Apr 08 #Python
python3使用diagrams绘制架构图的步骤
You might like
dedecms后台验证码总提示错误的解决方法
2007/03/21 PHP
php通过文件头检测文件类型通用代码类(zip,rar等)
2010/10/19 PHP
PHP支付系统设计与典型案例分享
2016/08/02 PHP
Laravel模糊查询区分大小写的实例
2019/09/29 PHP
特殊字符、常规符号及其代码对照表
2006/06/26 Javascript
JQuery 解析多维的Json数据格式
2009/11/02 Javascript
JQuery 动态扩展对象之另类视角
2010/05/25 Javascript
input按钮的事件处理大全
2010/12/10 Javascript
Javascript在IE和FireFox中的不同表现简析
2012/12/03 Javascript
js下拉菜单语言选项简单实现
2013/09/23 Javascript
jquery如何判断表格同一列不同行input数据是否重复
2014/05/14 Javascript
使用jquery实现的一个图片延迟加载插件(含图片延迟加载原理)
2014/06/05 Javascript
JS组件Bootstrap实现图片轮播效果
2016/05/16 Javascript
Node.js开启Https的实践详解
2016/10/25 Javascript
微信小程序购物商城系统开发系列-工具篇的介绍
2016/11/21 Javascript
详解javascript表单的Ajax提交插件的使用
2016/12/29 Javascript
javascript解析ajax返回的xml和json格式数据实例详解
2017/01/05 Javascript
[54:02]2018DOTA2亚洲邀请赛 4.1 小组赛 B组 IG vs VGJ.T
2018/04/03 DOTA
python dict 字典 以及 赋值 引用的一些实例(详解)
2017/01/20 Python
Python中支持向量机SVM的使用方法详解
2017/12/26 Python
python多进程中的内存复制(实例讲解)
2018/01/05 Python
python队列queue模块详解
2018/04/27 Python
Python Numpy计算各类距离的方法
2019/07/05 Python
Python Matplotlib简易教程(小白教程)
2020/07/28 Python
python 获取域名到期时间的方法步骤
2021/02/10 Python
韩国三大免税店之一:THE GRAND 中文免税店
2016/07/21 全球购物
百联网上商城:i百联
2017/01/28 全球购物
Orvis官网:自1856年以来,优质服装、飞钓装备等
2018/12/17 全球购物
Lookfantastic阿联酋官网:英国知名美妆护肤购物网站
2020/05/26 全球购物
商场中秋节广播稿
2014/01/17 职场文书
药品促销活动方案
2014/02/14 职场文书
5.12护士节演讲稿
2014/04/30 职场文书
反邪教标语
2014/06/23 职场文书
六一文艺汇演开幕词
2015/01/29 职场文书
暑假安全保证书
2015/02/28 职场文书
高中历史教学反思
2016/02/19 职场文书