最全总结!聊聊 Python 调用 JS 的几种方式
1. 前言
很多人学习python,不知道从何学起。
很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
很多已经做案例的人,却不知道如何去学习更加高深的知识。
那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!
QQ群:1097524789
日常 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)
但是经过反复测试发现,MAC 和 PC 在 Python3 环境下,使用 PyV8 会报各种奇怪的问题,所以不推荐使用!
更多功能可以参考:
https://github.com/emmetio/pyv8-binaries
7. 最后
上面总结了 Python 调用 JS 的 4 种方式
实际爬虫项目中,一般会先使用 node 命令进行一次测试,确保没问题后,再使用前 3 种方式的任意一种进行 Python 改写。
最全总结!聊聊 Python 调用 JS 的几种方式的更多相关文章
- Python调用接口的几种方式
1. requests import requests, jsongithub_url = 'https://api.github.com/user/repos'data = json.dumps({ ...
- 最全总结 | 聊聊 Python 办公自动化之 Excel(中)
1. 前言 上一篇文章中,我们聊到使用 xlrd.xlwt.xlutils 这一组合操作 Excel 的方法 最全总结 | 聊聊 Python 办公自动化之 Excel(上) 本篇文章将继续聊另外一 ...
- 最全总结 | 聊聊 Python 办公自动化之 Excel(下)
1. 前言 前面谈到 Python 处理 Excel 文件最常见的两种方式,即:xlrd/xlwt.openpyxl 其中, xlrd/xlwt 这一组合,xlrd 可以负责读取数据,而 xlwt ...
- 最全总结 | 聊聊 Python 办公自动化之 Word(下)
1. 前言 关于 Word 文档的读写,前面两篇文章分别进行了一次全面的总结 最全总结 | 聊聊 Python 办公自动化之 Word(上) 最全总结 | 聊聊 Python 办公自动化之 Word( ...
- Python 调用JS文件中的函数
Python 调用JS文件中的函数 1.安装PyExecJS第三方库 2.导入库:import execjs 3.调用JS文件中的方法 Passwd = execjs.compile(open(r&q ...
- 最全总结 | 聊聊 Python 办公自动化之 Word(上)
1. 前言 日常自动化办公中,使用 Python 真的能做到事半功倍! 在上一个系列中,我们对 Python 操作 Excel 进行了一次全面总结 最全总结 | 聊聊 Python 办公自动化之 Ex ...
- 最全总结 | 聊聊 Python 办公自动化之 Word(中)
1. 前言 上一篇文章,对 Word 写入数据的一些常见操作进行了总结 最全总结 | 聊聊 Python 办公自动化之 Word(上) 相比写入数据,读取数据同样很实用! 本篇文章,将谈谈如何全面读取 ...
- 最全总结 | 聊聊 Python 办公自动化之 PDF(上)
1. 前言 自动化办公,非 Python 莫属! 从本篇文章开始,我们继续聊聊自动化办公中另外一个常用系列:PPT 2. 准备一下 Python 操作 PPT 最强大的依赖库是:python-pptx ...
- 最全总结 | 聊聊 Python 办公自动化之 PPT(中)
1. 前言 上一篇文章简单地介绍了 PPT 的文档结构,并使用 python-pptx 这个依赖库完成对 PPT 文档最基本的操作 最全总结 | 聊聊 Python 办公自动化之 PPT(上) 作为 ...
随机推荐
- 【XCTF】ics-05
信息: 题目来源:XCTF 4th-CyberEarth 标签:PHP.伪协议 题目描述:其他破坏者会利用工控云管理系统设备维护中心的后门入侵系统 解题过程 题目给了一个工控管理系统,并提示存在后门, ...
- ## Java基础(二):变量类型
Java 变量类型 一.局部变量:类的方法中的变量 局部变量声明在方法.构造方法或者语句块中: 局部变量在方法.构造方语句块中被执行的时候创建,当他们执行完成后,变量被销毁 访问修饰符不能用于局部变量 ...
- scrapy 基础组件专题(七):scrapy 调度器、调度器中间件、自定义调度器
一.调度器 配置 SCHEDULER = 'scrapy.core.scheduler.Scheduler' #表示scrapy包下core文件夹scheduler文件Scheduler类# 可以通过 ...
- 你有认真了解过自己的“Java对象”吗? 渣男
对象在 JVM 中是怎么存储的 对象头里有什么? 文章收录在 GitHub JavaKeeper ,N线互联网开发必备技能兵器谱,有你想要的. 作为一名 Javaer,生活中的我们可能暂时没有对象,但 ...
- P1092 虫食算(洛谷)
今天做了一道题,我之前吹牛的时候曾经说:“这个题我觉得深搜剪枝一下就可以了.”. 我觉得我之前说的没错“这个题深搜剪枝亿下,再加点玄学就可以了!” 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子 ...
- js 判断传入参数是域名还是地址
var get = function(url) { if(location.protocol === "http") { return url; } var reg = /^(ht ...
- Git报错问题集锦
git merge合并时遇上refusing to merge unrelated histories的解决方案 如果git merge合并的时候出现refusing to merge unrelat ...
- mysql 联合唯一
CREATE TABLE `NewTable` ( `id` int NOT NULL , `name` varchar(255) NULL , `phone` varchar(255) NULL , ...
- C++头文件居然可以这么打!!!! 长见识了!!!
返回主页 longdie 这人,生于天,立于地,为的就是顶天立地. 未来的答案早已被宇宙计算好了,人类自出现,答案就在那里,人类灭亡了,答案也在那里,,但是人活着,不就是为了看看未来发生了什么吗?如果 ...
- laravel报错1071 Specified key was too long; max key length is 1000 bytes
Laravel 默认使用utf8mb4字符编码,而不是的utf8编码.因此运行php artisan migrate会出现如下错误: [Illuminate\Database\QueryExcepti ...