在日常使用Python做爬蟲,一般會用到以下手段:
- 請求URL,回傳HTML文本,然后通過xpath、css或者re,提取資料
- 有些網頁的資料通過AJAX異步請求加載,此時找到對應的介面,呼叫并直接使用介面回傳的資料
- 有時候如果網站反爬或安全機制比較高時,則會做一些驗證或者加密,比如cookie內必須攜帶token等資訊,而這些資訊是通過混淆過的js代碼計算得出的,
針對1,應該是爬取大多數沒有任何安全機制并且是靜態網頁時,常用手段,而2是提取資料最為快速的,但是介面并不是總是回傳我們最喜歡的json字串,有可能是一段js代碼定義的變數資料,針對3則更為頭痛,如果在Python匯總能運行js代碼,則可能會解決掉我們大部分的煩惱,本文即講解一個Python包,用于直接在Python代碼中直接運行js代碼,然后得到我們感興趣的函式、資料或者js代碼運行之后的結果,
一、js2py庫概述
js2py是眾多可以在Python中運行js代碼比較優秀的庫,
安裝js2py方法如下:
pip install js2py
js2py中有以下兩個比較關鍵的方法:
| 方法 | 解釋 | 示意 |
| js2py.eval_js(js_string) | 直接運行含有js代碼的字串(或js檔案),并得出結果 | js_string='var a=10' js2py.eval_js(js_string) #輸出10 |
| js2py.EvalJs() | 生成一個EvalJs物件 可通過該物件的execute方法來運行一段js代碼(或js檔案),并得到對應的變數和物件(即抑制輸出,得到變數和物件,便于后續直接使用) 可通過該物件的eval()方法來運行一段js代碼,并得到結果 | js_string='var a=10' js_obj=js2py.EvalJs() js_obj.execute(js_string) js_obj.a #輸出為10 |
二、抽取js代碼運行結果
import js2py
string='var db={chars:["a","b","c","d","f","g","h","j","k","m","n","p","q","r","s","t","w","x","y","z"],datas:[["005970","國泰消費優選股票","GTXFYXGP","1.9082","1.9082","1.8657","1.8657","0.0425","2.28","開放申購","開放贖回","","1","0","1","","1","0.15%","0.15%","1","1.50%"],["004069","南方中證全指證券公司ETF聯接A","NFZZQZZQGSETFLJA","1.1438","1.1438","1.1212","1.1212","0.0226","2.02","開放申購","開放贖回","","1","0","2","","1","0.12%","0.12%","1","1.20%"]],count:["9981","3745","1653","4583"],record:"10481",pages:"5241",curpage:"1",indexsy:[-0.04,-0.34,-0.03,],showday:["2021-03-05","2021-03-04"]}'
mydict=js2py.eval_js(string) #最后會將string內定義的物件,變為Python字典并賦值給mydict
string='''
function add(a, b) {
return a + b
}
'''
myadd=js2py.eval_js(string) #會得到一個add函式并賦值給myadd,后續可通過myadd直接呼叫
- 以上第一個string,便是作者在爬取天天基金的基金資料時,發現該網站介面回傳的基本都是一個js陳述句,在該陳述句內定義了回傳的資料,當然,如果不通過js2py,也可以將該string通過Python的eval或者exec最終決議成Python字典,但比較繁瑣(大概思路即使用字串方法,將無用的字符洗掉掉,然后將字串變成一個Python字典的定義格式,最后運行eval或者exec函式即可)
- 以上第二個string,即一個字串,該字串內定義了一個js函式,此時便可以得到該函式并賦值給Python變數,后續便可以通過該變數呼叫該函式,并且好像是該函式是在Python內部定義的一樣
三、提取js陳述句內變數和物件等
import js2py
js_obj=js2py.EvalJs()
string='''
var a=10
function func(a,b){
return a*b
}
'''
js_obj.execute(string)
js_obj.a #輸出為10
js_obj.func #為func函式
js_obj.func(3,4) #輸出為12
- 以上示意,變得更有意思,可以通過execute方法,運行下js代碼,先不輸出結果,而是得到這里面定義的變數、函式等,然后把這些作為屬性附加給js_obj物件,后續便可以通過該物件訪問到這些屬性,這樣會更加直觀和靈活,好像是直接在Python中寫js代碼一樣
四、其他
當然,Python還有其他運行js代碼的庫,但是作者感覺js2py整體是最契合Python的,甚至語法都基本沒什么變化,故推薦使用該庫
該庫還有其他很多方法和用途,不過以上是最為常用的場景,讀者如果需要或感興趣,可以進一步研究學習,不顧如果能掌握好以上方法,基本可以滿足90%的日常需要了,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/267476.html
標籤:其他
上一篇:劍指 Offer 68 - I. 二叉搜索樹的最近公共祖先
下一篇:21/3/6 hashmap
