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判断文本中消息重复次数的方法
Apr 27 Python
Python实现删除列表中满足一定条件的元素示例
Jun 12 Python
python爬取各类文档方法归类汇总
Mar 22 Python
python实现类之间的方法互相调用
Apr 29 Python
Django中日期处理注意事项与自定义时间格式转换详解
Aug 06 Python
Python实现的读取/更改/写入xml文件操作示例
Aug 30 Python
Python实现Linux监控的方法
May 16 Python
Python中查看变量的类型内存地址所占字节的大小
Jun 26 Python
python3 图片 4通道转成3通道 1通道转成3通道 图片压缩实例
Dec 03 Python
Pytorch中.new()的作用详解
Feb 18 Python
No module named ‘win32gui‘ 的解决方法(踩坑之旅)
Feb 18 Python
python如何实现递归转非递归
Feb 25 Python
Python WSGI 规范简介
使用pytorch实现线性回归
pytorch实现线性回归以及多元回归
python如何获取网络数据
Apr 11 #Python
Pytorch 使用tensor特定条件判断索引
selenium.webdriver中add_argument方法常用参数表
Apr 08 #Python
python3使用diagrams绘制架构图的步骤
You might like
WordPress用户登录框密码的隐藏与部分显示技巧
2015/12/31 PHP
PHP基于PDO调用sqlserver存储过程通用方法【基于Yii框架】
2017/10/07 PHP
支持汉转拼和拼音分词的PHP中文工具类ChineseUtil
2018/02/23 PHP
PHP hebrev()函数用法讲解
2019/02/21 PHP
解析JavaScript中的不可见数据类型
2013/12/02 Javascript
jQuery扁平化风格下拉框美化插件FancySelect使用指南
2015/02/10 Javascript
JavaScript判断是否为数字的4种方法及效率比较
2015/04/01 Javascript
第二次聊一聊JS require.js模块化工具的基础知识
2016/04/17 Javascript
jQuery获取attr()与prop()属性值的方法及区别介绍
2016/07/06 Javascript
JQuery为元素添加样式的实现方法
2016/07/20 Javascript
Mac下安装vue
2018/04/11 Javascript
深入理解Vue 的钩子函数
2018/09/05 Javascript
微信小程序日历/日期选择插件使用方法详解
2018/12/28 Javascript
vue实现计步器功能
2019/11/01 Javascript
vue 组件开发原理与实现方法详解
2019/11/29 Javascript
jquery实现直播视频弹幕效果
2020/02/25 jQuery
微信公众号中的JSSDK接入及invalid signature等常见错误问题分析(全面解析)
2020/04/11 Javascript
微信小程序 获取手机号 JavaScript解密示例代码详解
2020/05/14 Javascript
JavaScript实时更新当前的时间的示例代码
2020/07/15 Javascript
利用JavaScript模拟京东按键输入功能
2020/12/01 Javascript
原生JavaScript实现留言板
2021/01/10 Javascript
Python中的yield浅析
2014/06/16 Python
python中反射用法实例
2015/03/27 Python
python+selenium识别验证码并登录的示例代码
2017/12/21 Python
Python 将pdf转成图片的方法
2018/04/23 Python
Python实现求解一元二次方程的方法示例
2018/06/20 Python
pytorch 查看cuda 版本方式
2020/06/23 Python
keras输出预测值和真实值方式
2020/06/27 Python
C#可否对内存进行直接的操作
2015/02/26 面试题
《社戏》教学反思
2014/04/15 职场文书
大学生感恩父母演讲稿
2014/08/28 职场文书
2014个人反腐倡廉思想汇报
2014/09/15 职场文书
2016年“世界气象日”广播稿
2015/12/17 职场文书
分享:关于学习的励志名言赏析
2019/08/16 职场文书
解决使用了nginx获取IP地址都是127.0.0.1 的问题
2021/09/25 Servers
nginx lua 操作 mysql
2022/05/15 Servers