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 ftp上传文件
Feb 13 Python
利用Python获取赶集网招聘信息前篇
Apr 18 Python
使用Python实现租车计费系统的两种方法
Sep 29 Python
Python函数的参数常见分类与用法实例详解
Mar 30 Python
Python Threading 线程/互斥锁/死锁/GIL锁
Jul 21 Python
Python 经典算法100及解析(小结)
Sep 13 Python
线程安全及Python中的GIL原理分析
Oct 29 Python
Python使用psutil获取进程信息的例子
Dec 17 Python
Python版中国省市经纬度
Feb 11 Python
Python bytes string相互转换过程解析
Mar 05 Python
python 操作excel表格的方法
Dec 05 Python
Python编程super应用场景及示例解析
Oct 05 Python
Python WSGI 规范简介
使用pytorch实现线性回归
pytorch实现线性回归以及多元回归
python如何获取网络数据
Apr 11 #Python
Pytorch 使用tensor特定条件判断索引
selenium.webdriver中add_argument方法常用参数表
Apr 08 #Python
python3使用diagrams绘制架构图的步骤
You might like
漂亮但不安全的CTB
2006/10/09 PHP
最小化数据传输――在客户端存储数据
2006/10/09 PHP
PHP5.3与5.5废弃与过期函数整理汇总
2014/07/10 PHP
一个简单的php MVC留言本实例代码(必看篇)
2016/09/22 PHP
PHP+jQuery实现即点即改功能示例
2019/02/21 PHP
一些不错的js函数ajax
2008/08/20 Javascript
javascript parseInt与Number函数的区别
2010/01/21 Javascript
用js实现输入提示(自动完成)的实例代码
2013/06/14 Javascript
jQuery中width()方法用法实例
2014/12/24 Javascript
JavaScript的jQuery库中function的存在和参数问题
2015/08/13 Javascript
深入浅析AngularJS中的module(模块)
2016/01/04 Javascript
jQuery AJAX timeout 超时问题详解
2016/06/21 Javascript
JS+CSS3模拟溢出滚动效果
2016/08/12 Javascript
localStorage实现便签小程序
2016/11/28 Javascript
如何在Angular应用中创建包含组件方法示例
2019/03/23 Javascript
详解elementui之el-image-viewer(图片查看器)
2019/08/30 Javascript
ant-design-vue 实现表格内部字段验证功能
2019/12/16 Javascript
[01:26]神话结束了,却也刚刚开始——DOTA2新英雄玛尔斯驾临战场
2019/03/10 DOTA
Python中的各种装饰器详解
2015/04/11 Python
Python爬取国外天气预报网站的方法
2015/07/10 Python
Python Numpy 数组的初始化和基本操作
2018/03/13 Python
python简单操作excle的方法
2018/09/12 Python
python数据结构之线性表的顺序存储结构
2018/09/28 Python
python Pexpect 实现输密码 scp 拷贝的方法
2019/01/03 Python
python接口自动化(十七)--Json 数据处理---一次爬坑记(详解)
2019/04/18 Python
python GUI库图形界面开发之PyQt5中QWebEngineView内嵌网页与Python的数据交互传参详细方法实例
2020/02/26 Python
Django rest framework分页接口实现原理解析
2020/08/21 Python
利于python脚本编写可视化nmap和masscan的方法
2020/12/29 Python
python实现双人五子棋(终端版)
2020/12/30 Python
利用python为PostgreSQL的表自动添加分区
2021/01/18 Python
学点简单的Django之第一个Django程序的实现
2021/02/24 Python
SmartBuyGlasses美国官网:太阳眼镜和眼镜
2017/08/20 全球购物
经理秘书岗位职责
2013/11/14 职场文书
会计专业大学生职业生涯规划范文
2014/01/11 职场文书
出国留学导师推荐信
2015/03/26 职场文书
Spring Data JPA框架持久化存储数据到数据库
2022/04/28 Java/Android