「Python爬虫」如何在Python 中执行JavaScript呢?
全民python
2019-09-02 01:13:07
阅读(478)
(0)
> 在使用爬虫中,经常会遇到网页请求数据是经过 JS 处理的,特别是模拟登录时可能有加密请求。而目前绝大部分前端 JS 代码都是经过混淆的,可读性极低,想理解代码逻辑需要花费大量时间。这时不要着急使用 Selenium 暴力解决,毕竟 Selenium 严重拖慢爬虫效率,我们可以尝试使用一些第三方库,来直接执行前端 JS 代码得到处理过后的结果。
## PyExecJS
**PyExecJS**,是一个可以运行`JavaScript`代码的`Python`第三方库,这个库主要是将 JS 代码运行在本地的 JS 环境中。在使用这个库之前需要确保本地环境安装了JS环境,官方推荐了4种:
- PyV8
- Node.js
- PhantomJS
- Nashorn
当然缺点是必须安装一种环境导致不是很轻量,而且调用时有一个启动环境过程,还是有明显缓慢的。
### PyExecJS安装
#### JS环境安装
先解决JS环境,我们这里使用`Node.js`,安装方便,执行效率也高。
进入官网,下载对应包,我这里是windows下安装,所以直接选择windows安装包

安装过程很简单,一路“下一步”就可以了(傻瓜式安装)。
安装完成之后,打开命令行工具,输入 node -v,如下图,如果出现相应的版本号,则说明安装成功。

#### PyExecJS安装
直接使用pip命令进行安装即可:
```
pip install PyExecJS
```
### PyExecJS使用
#### 引入模块
要使用PyExecJS模块,则需要引入
```python
import execjs # 注意引入的是execjs而不是写成PyExecJS
```
#### PyExecJS 使用实例
##### 执行js语句
```python
import execjs
print(execjs.get().name) # 查看调用的环境
#调用变量
result = execjs.eval("'python java php'.split(' ')")
print(result)
# 通过compile命令转成一个js对象
context = execjs.compile("""
function add(x,y){
return x + y;
}
""")
sum = context.call("add", 2, 3) # 函数名, 参数..
print(sum)
```
输出:
```
Node.js (V8)
['python', 'java', 'php']
5
```
##### 执行js文件
我们新建一个`test.js`文件,里面内容同上:
```javascript
function add(x, y){
return x + y;
}
var sum = add(2,3) + 5;
```
python代码:
```python
import execjs
# 读取js文件
with open('test.js', 'r', encoding='utf-8') as f:
js = f.read()
# 通过compile命令转换成一个js对象
js_obj = execjs.compile(js)
# 调用function函数
res = js_obj.call('add', 1,2)
print(res)
# 调用变量
res = js_obj.eval('sum')
print(res)
```
输出结果:
```
3
10
```
## PyV8
**PyV8**,这是 Google 官方将 Chrome V8 引擎用 Python 封装的库,和 `PyExecJS` 相比,这个库很轻量,不需要额外装 JS 环境,因为 V8 本身就是环境,同时也因为不需要启动外部环境,执行速度很快。
### PyV8安装:
Python3 安装不要使用pip,因为官方只支持 Python2,需要在这里下载对应系统的二进制文件:然后解压后将 PyV8.py 与 _PyV8.so (如so不是这个名字需要改成这样) 两文件复制到 Python 的 site-packages 目录下,如 /usr/local/lib/python3.6/site-packages。
### PyV8使用
```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 代码,转译过来的大概率会报错… 所以只建议先尝试一下,如果报错及时更换上面的库。
### Js2Py安装
直接pip命令安装:
```
pip install js2py
```
### Js2Py使用
```python
import js2py
add = js2py.eval_js("""
function add(x, y) {
return x + y;
}
""")
print(add) # 可以看到大括号里已被转译
'function add(x, y) { [python code] }'
print(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)
```
针对现在大部分的网站都是使用js加密,js加载的,并不能直接抓取出来,这时候就不得不适用我们上面学习的三个库来执行js语句。至于哪个库根据情况,一般推荐使用**PyExecJS**库。
后续我们会针对js混淆加密,也就是获取的是一对乱七八糟的js代码进行破解。
转载此文章须经作者同意,并请附上本页链接:www.qmpython.com/articles/detail-23.html
赞(0)
关闭
感谢您的支持,我会继续努力的!
扫码打赏,你说多少就多少
分享:
打开微信“扫一扫”
x
打开网页后点击屏幕右上角分享按钮,分享到微信朋友或朋友圈