51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

爬虫必备:Python 执行 JS 代码 —— PyExecJS、PyV8、Js2Py

在使用爬虫中,经常会遇到网页请求数据是经过 JS 处理的,特别是模拟登录时可能有加密请求。而目前绝大部分前端 JS 代码都是经过混淆的,可读性极低,想理解代码逻辑需要花费大量时间。这时不要着急使用 Selenium 暴力解决,毕竟 Selenium 严重拖慢爬虫效率,我们可以尝试使用一些第三方库,来直接执行前端 JS 代码得到处理过后的结果。

PyExecJS {#pyexecjs}

这个库主要是将 JS 代码运行在本地的 JS 环境中,优点是我们有多种 JS 环境的选择,官方推荐了 PyV8、Node.js、PhantomJS、Nashorn 四种,当然缺点是必须安装一种环境导致不是很轻量,而且调用时有一个启动环境过程,还是有明显缓慢的。

安装方式 {#安装方式}

先解决 JS 环境,这里推荐安装 Node.js ,安装方便,执行效率也高。
然后 pip install PyExecJS 就可以了。

使用例子 {#使用例子}

|---------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 13 | hljs python >>> import execjs >>> execjs.get().name # 查看调用的环境 'Node.js (V8)' >>> ctx = execjs.compile(""" # 执行 JS 语句 ... function add(x, y) { ... return x + y; ... } ... """) >>> ctx.call("add", 1, 2) 3 >>> with open('./test.js') as f: # 执行 JS 文件 ... ctx = execjs.compile(f.read()) ... ctx.call('add', 1, 2) |

PyV8 {#pyv8}

这是 Google 官方将 Chrome V8 引擎用 Python 封装的库,和 PyExecJS 相比,这个库很轻量,不需要额外装 JS 环境,因为 V8 本身就是环境,同时也因为不需要启动外部环境,执行速度很快。

安装方式 {#安装方式-1}

Python3 安装不要使用pip,因为官方只支持 Python2,需要在这里下载对应系统的二进制文件:https://github.com/emmetio/pyv8-binaries
然后解压后将 PyV8.py 与 _PyV8.so (如so不是这个名字需要改成这样) 两文件复制到 Python 的 site-packages 目录下,如 /usr/local/lib/python3.6/site-packages

使用例子 {#使用例子-1}

|-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 | hljs python >>> import PyV8 # 注意大小写 >>> with PyV8.JSContext() as ctx: ... ctx.eval(""" ... function add(x, y) { ... return x + y; ... } ... """) ... ctx.locals.add(1, 2) |

Js2Py {#js2py}

最后这个库,作用是将 JS 代码直接转译成 Python 代码,这种方式可以摆脱调用 JS 环境的瓶颈,但遗憾的是如果用于很长的混淆 JS 代码,转译过来的大概率会报错... 所以只建议先尝试一下,如果报错及时更换上面的库。

安装方式 {#安装方式-2}

pip install js2py

使用例子 {#使用例子-2}

|---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | hljs python >>> import js2py >>> add = js2py.eval_js(""" ... function add(x, y) { ... return x + y; ... } ... """) >>> add # 可以看到大括号里已被转译 'function add(x, y) { [python code] }' >>> add(1, 2) 3 >>> # 使用下边这个方法可以输出转译后的代码 >>> # 可以保存到文件里,下次不需要再次转译 >>> print(js2py.translate_js('var x = 1')) from js2py.pyjs import * # setting scope var = Scope( JS_BUILTINS ) set_global_object(var) # Code follows: var.registers(['x']) var.put('x', Js(1.0)) |

实战技巧 {#实战技巧}

当选择完合适的库后,如果你还不明白在浏览器里进行 Debug 的方法,那需要去搜索关键词先学习一下。

接下来就是定位目标网页需要调用的 JS 函数,这里实在无法详述,因为每个网站的写法都大不相同。

不过只要你通过 Debug ,查看数据从请求开始,每一步都经过了哪些 JS 函数,又输出成什么样的数据,就可以顺藤摸瓜找到一些可疑的函数,然后将这些方法逐一复制出来,通过上面的库传入参数执行,看是否和目标网页处理后的数据一致,就可以找到目标函数。

赞(0)
未经允许不得转载:工具盒子 » 爬虫必备:Python 执行 JS 代码 —— PyExecJS、PyV8、Js2Py