爬蟲必備:Python執行JS代碼——PyExecJS、PyV8、Js2Py

NO IMAGE

在使用爬蟲中,經常會遇到網頁請求數據是經過 JS 處理的,特別是模擬登錄時可能有加密請求。而目前絕大部分前端 JS 代碼都是經過混淆的,可讀性極低,想理解代碼邏輯需要花費大量時間。這時不要著急使用 Selenium 暴力解決,畢竟 Selenium 嚴重拖慢爬蟲效率,我們可以嘗試使用一些第三方庫,來直接執行前端 JS 代碼得到處理過後的結果。

PyExecJS

這個庫主要是將 JS 代碼運行在本地的 JS 環境中,優點是我們有多種 JS 環境的選擇,官方推薦了 PyV8、Node.js、PhantomJS、Nashorn 四種,當然缺點是必須安裝一種環境導致不是很輕量,而且調用時有一個啟動環境過程,還是有明顯緩慢的。

安裝方式

先解決 JS 環境,這裡推薦安裝 Node.js ,安裝方便,執行效率也高。
然後 pip install PyExecJS 就可以了。

使用例子

>>> 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

這是 Google 官方將 Chrome V8 引擎用 Python 封裝的庫,和 PyExecJS 相比,這個庫很輕量,不需要額外裝 JS 環境,因為 V8 本身就是環境,同時也因為不需要啟動外部環境,執行速度很快。

安裝方式

Python3 安裝不要使用pip,因為官方只支持 Python2,需要在這裡下載對應系統的二進制文件:github.com/emmetio/pyv…
然後解壓後將 PyV8.py 與 _PyV8.so (如so不是這個名字需要改成這樣) 兩文件複製到 Python 的 site-packages 目錄下,如 /usr/local/lib/python3.6/site-packages

使用例子

>>> import PyV8  # 注意大小寫
>>> with PyV8.JSContext() as ctx:
...     ctx.eval("""
...         function add(x, y) {
...             return x + y;
...         }
...     """)
...     ctx.locals.add(1, 2)

Js2Py

最後這個庫,作用是將 JS 代碼直接轉譯成 Python 代碼,這種方式可以擺脫調用 JS 環境的瓶頸,但遺憾的是如果用於很長的混淆 JS 代碼,轉譯過來的大概率會報錯… 所以只建議先嚐試一下,如果報錯及時更換上面的庫。

安裝方式

pip install js2py

使用例子

>>> 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 函數,又輸出成什麼樣的數據,就可以順藤摸瓜找到一些可疑的函數,然後將這些方法逐一複製出來,通過上面的庫傳入參數執行,看是否和目標網頁處理後的數據一致,就可以找到目標函數。


最後,關注我的微信公眾號:面向人生編程

爬蟲必備:Python執行JS代碼——PyExecJS、PyV8、Js2Py

無論什麼樣的編程思想,都不該只存留在代碼之中,更應伴隨於整個人生旅途,這個公眾號不只聊技術,還會聊產品/互聯網/經濟學等廣泛話題,所以也歡迎非程序員關注。

相關文章

Markdown直接轉換公眾號文章,不再為排版花時間

又一家數據公司被查,爬蟲到底做錯了什麼?

爬蟲工程師分享:三步就搞定Android逆向

爬蟲工程師常用的Chrome插件