Python 执行 js 的处理方法
爬虫开发中经常会遇到 js 反爬,为应对反爬,最快的方法就是在 python 中直接执行 js 获取结果。
常用的第三方库有:js2py、execjs、pyv8
第三方库 | 使用心得 | 项目状态 | 开源地址 |
---|---|---|---|
Js2Py | 速度较快,不支持 dom | 维护中 | https://github.com/PiotrDabkowski/Js2Py |
PyExecJS | 功能较全,性能较差 | 停止维护 | https://github.com/doloopwhile/PyExecJS |
pyv8 | 没用过 | 停止维护 | https://github.com/emmetio/pyv8-binaries |
1、Js2Py
1.1 工作原理
将 js 编译成 python 执行,优雅灵活,速度较快,但是部分功能暂时无法实现。
比如目前不支持 dom 操作,所以 js 中有 dom 操作的,可以先用 execjs 。
1.2 安装
pip install js2py
1.3 使用
import js2py # 例1 js_text = """ function add(a, b) {return a + b} """ js = js2py.EvalJs() js.execute(js_text) total = js.add(11, 22) print(total) # 例2 js_text = """ c = base; function add(a, b) {return a + b + c} """ js = js2py.EvalJs({'base': 100}) js.execute(js_text) total = js.add(11, 22) print(total, js.c)
2、PyExecJS
2.1 工作原理
PyExecJS 是来自 Ruby的 ExecJS 的移植。PyExecJS 通过文本传达 JavaScript 运行,并且运行缓慢。另一个缺点是它不完全支持运行时特定的功能。
依赖 node.js,但是比 Js2Py 支持的功能要全一些,比如 dom 支持。所以,目前可以作为 Js2Py 的一个补充工具,遇到一般 js 时,还是建议优先选择 Js2Py 。
2.2 安装
pip install PyExecJS
2.3 使用
import execjs # 例1 js_text = """ 'red yellow blue'.split(' ') """ t = execjs.eval(js_text) print(t) # 例2 js_text = """ t=100 function add(a, b) {return a + b} """ js = execjs.compile(js_text) # 获取代码编译完成后的对象 total = js.call('add', 10, 20) print(total)
3、Js 中含有 window, document 的处理
当 Js 中含有 window, document 时,就会报错了,这时就需要安装 jsdom 进行处理。
3.1 需要安装 jsdom
执行安装命令后,会在当前路径下,生成一个文件夹 node_modules,后续将在 py 中引用。
需要注意路径,建议和当前的 py 脚本放在一个路径下
npm install jsdom
3.2 修改 js,引入 jsdom
在 js 代码前面,加入如下代码,用来调用 jsdom,引入 dom 对象
js_text = """ const jsdom = require("jsdom"); const { JSDOM } = jsdom; const dom = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`); window = dom.window; document = window.document; XMLHttpRequest = window.XMLHttpRequest;
另外,这边需要把 atob 改为 window.atob,然后就 ok 了
import execjs js_text = """ const jsdom = require("jsdom"); const { JSDOM } = jsdom; const dom = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`); window = dom.window; document = window.document; XMLHttpRequest = window.XMLHttpRequest; function add(a) { document.e = 100 return window.atob(document.e + a)} """ js = execjs.compile(js_text, cwd='node_modules') # 获取代码编译完成后的对象 total = js.call('add', 10) print(total)
版权声明:如无特殊说明,文章均为本站原创,转载请注明出处
本文链接:http://blog.turboway.top/article/PyExecJS/
许可协议:署名-非商业性使用 4.0 国际许可协议