python爬蟲之JS逆向
Python爬蟲之JS逆向案例
由於在爬取數據時,遇到請求頭限制屬性為動態生成,現將解決方式整理如下:
JS逆向有兩種思路:
一種是整理出js文件在Python中直接使用execjs調用js文件(可見我的另一篇文章《 python爬蟲之企某科技JS逆向 》)。
一種是根據JS中的邏輯,使用Python重寫相應的方法。
本文介紹的是第二種使用Python重寫JS的方法
需求:爬取某區塊鏈網站http://www.oklink.com/zh-cn/btc/tx-list?limit=20&pageNum=1數據
遇到的問題:目標網站的數據是通過ajax請求相應的接口獲取數據,在請求頭中需要攜帶x-apiKey(根據時間動態生成的),我們需要解決的就是整理出動態生成x-apiKey的方法。
解決思路:根據關鍵字"x-apiKey”在網站的JS中找到相應的定義,然後使用python重寫方法,在請求接口時實時生成相應的x-apiKey
第一步:在瀏覽器中使用開發者工具找到相應的接口
請求地址:http://www.oklink.com/api/explorer/v1/btc/transactionsNoRestrict?t=1654916647499&limit=20&offset=0
請求類型:GET
請求頭:x-apiKey:
LWIzMWUtNDU0Ny05Mjk5LWI2ZDA3Yjc2MzFhYmEyYzkwM2NjfDI3NjYwMjc3NTg2MTAzNjk=
第二步:找到x-apiKey的定義方法
t.headers.common["x-apiKey"] = n.Z.getApiKey()
根據上面的代碼中看到x-apiKey是由getApiKey這個方法返回的,通過getApiKey搜索找到相應的定義如下:
1.接下就是解析這個getApiKey方法了。
{ key: "getApiKey", value: function() { var t = (new Date).getTime() , e = this.encryptApiKey(); return t = this.encryptTime(t), this.comb(e, t) } }
1).變量t就是獲取當前時間戳
2).變量e是調用encryptApiKey這個方法
3).變量t是encryptTime(t)這個方法處理後的返回
4).最後通過comb(e,t)個方法生成最終的apiKey
2.encryptTime方法
key: "encryptApiKey", value: function() { var t = this.API_KEY , e = t.split("") , r = e.splice(0, 8); return e.concat(r).join("") }
1).變量t是一個常量字符串API_KEY,往上找到初始化值為this.API_KEY = "a2c903cc-b31e-4547-9299-b6d07b7631ab"
2).變量e是將上面的t分隔成數組
3).變量r:從變量e中刪除前8個字符串,並將e的前8個元素組成的數組賦值給r。同時變量e刪除了前8個元素
4).最終將e和r合併在一起並轉為字符串
3.encryptTime方法
key: "encryptTime", value: function(t) { var e = (1 * t + 1111111111111).toString().split("") , r = parseInt(10 * Math.random(), 10) , n = parseInt(10 * Math.random(), 10) , o = parseInt(10 * Math.random(), 10); return e.concat([r, n, o]).join("") }
1).變量e為將入參t加上1111111111111然後轉為字符串,分隔為數組
2).變量r、n、o三個是生成10以內的隨機整數
3).最後返回的是e和[r,n,o]數組合並,轉為字符串返回
4.comb方法
key: "comb", value: function(t, e) { var r = "".concat(t, "|").concat(e); return window.btoa(r) }
1).變量r是由入參t和e中間加上|然後拼在一起的
2).window.btoa是返回的base64加密編碼
3)comb方法最終返回的就是我們需要的x-apiKey的值了
5.將上面的JS邏輯轉為Python代碼如下:
def get_api_key(): cur_time = int(time.time() * 1000) api_key = 'a2c903cc-b31e-4547-9299-b6d07b7631ab' key_1 = api_key[0:8] key_2 = api_key[8:] encrypt_api_key = key_2 + key_1 string = str(cur_time + 1111111111111) r = random.randint(0, 9) n = random.randint(0, 9) o = random.randint(0, 9) encrypt_time = '%s%s%s%s' % (string, r, n, o) new_key = encrypt_api_key + '|' + encrypt_time # 轉為bytes-like object new_key = new_key.encode('utf-8') # 將bytes-like object轉成字符串類型 return str(base64.b64encode(new_key), encoding='utf-8')
至此,我們就得到了動態生成的x-apiKey,接下來繼續操作吧。
- Android Jetpack Navigation基本使用
- 我所使用的生產 Java 17 啟動參數
- 【clickhouse專欄】對標mongodb存儲類JSON數據文檔統計分析
- 【Java面試】Mysql為什麼使用B Tree作為索引結構
- C 煉氣期之數據是主角
- 華為雲Stack首席架構師:打造“稱手”的數字化工具,答好政企IT數字化轉型這道必選題
- ShardingSphere 異構遷移最佳實踐:將3.5億量級的顧客系統 RTO 減少60倍
- 我的第一個springboot starter
- 機器學習服務助應用內文本語種在線和離線檢測
- go-zero微服務實戰系列(三、API定義和表結構設計)
- Jetpack架構組件學習(3)——Activity Results API使用
- 這篇SpringCloud GateWay 詳解,你用的到
- Spring Cloud入門看這一篇就夠了
- 加速訓練之並行化 tf.data.Dataset 生成器
- 羅景:連接效率優化實踐
- .net core 拋異常對性能影響的求證之路
- python爬蟲之JS逆向
- 深度學習與CV教程(14) | 圖像分割 (FCN,SegNet,U-Net,PSPNet,DeepLab,RefineNet)
- Linux查看日誌文件寫入速度的4種方法
- iNeuOS工業互聯網操作系統,在線報表(Excel)開發工具