聲明:本文章中所有內(nèi)容僅供學(xué)習(xí)交流,不可用于任何商業(yè)用途和非法用途,否則后果自負(fù),如有侵權(quán),請(qǐng)聯(lián)系作者立即刪除!由于本人水平有限,如有理解或者描述不準(zhǔn)確的地方,還望各位大佬指教!!
練習(xí)網(wǎng)站:
Q3JhenkgUHJvTW9ua2V5IGh0dHBzOi8vd3d3LnBhbnpob3UuZ292LmNuL3p3Z2tfMTU4NjEvemZ4eGdremwvZmR6ZGdrbnJfNTgzNTQxNi9senlqXzU4MzU0MTcvemZ3al81ODM1NDE4L2luZGV4Lmh0bWw=
網(wǎng)站分析:
打開開發(fā)者工具,發(fā)現(xiàn)數(shù)據(jù)走的是wss協(xié)議,如圖
?前面的文章中也有介紹過,以下特征就是代表著wss協(xié)議
既然知道了數(shù)據(jù)走的wss協(xié)議,那么我們就看他的wss鏈接,如圖。但是我們發(fā)現(xiàn)wss鏈接是由幾個(gè)加密值拼接的,那么我們的任務(wù)就是破解加密值以及尋找解密方法和入口
實(shí)戰(zhàn)操作:
想必細(xì)心的大佬們都能發(fā)現(xiàn),在ajax接口中,其響應(yīng)的cookie值是和wss鏈接是吻合的,如圖,那么,我們就可以大膽的請(qǐng)求這個(gè)接口了
然后接口還需要傳參,參數(shù)值是加密的,那么我們就需要破解加密參數(shù)
又經(jīng)過跟棧,找到了參數(shù)的加密入口,i 即為加密值,我們又發(fā)現(xiàn)請(qǐng)求接口時(shí),請(qǐng)求頭有對(duì)Fetch-Mode(為定值)和etag兩個(gè)值有校驗(yàn),那么我們同時(shí)還要拿到etag的值
而 i 的值是有 r 函數(shù)對(duì) L 進(jìn)行操作的,那么我們可以模擬 L 的生成(對(duì)url進(jìn)行改變即可),但是我們卻沒有 r 函數(shù)
?往上檢查js代碼,發(fā)現(xiàn)了 r 的生成位置
看到 r = n(42),并跟進(jìn)去,就知道 r 是由webpack生成的,這里的webpack的處理可以參考前面文章,這里就不做過多介紹了
?當(dāng) r 和 etag 復(fù)原之后,就可以正常生成加密參數(shù)了, 如圖
運(yùn)行結(jié)果如圖
?那么我們就能拿到ajax接口的響應(yīng)cookie值了,就可以生成wss鏈接了,如圖
import execjs
from spider_util.utils import *
def data_sign():
# 讀取js文件
with open('./2.js', 'r', encoding='utf-8') as f:
reader = f.read()
# 加載編譯讀取內(nèi)容
loader = execjs.compile(reader)
# 調(diào)用js文件中的方法
r = loader.call('fjm_panzhou_sdk')
# 返回結(jié)果
return r
data_sign = data_sign()
etag = data_sign[0]
param = data_sign[1]
headers = {
"content-type": "application/json; charset=UTF-8",
"etag": etag,
"fetch-mode": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
}
url = "https://www.panzhou.gov.cn/1ywuKELSO2ahQuWZ/api/v1/sessions"
data = {
"data": param
}
data = json.dumps(data, separators=(',', ':'))
response = requests.post(url, headers=headers, data=data)
wss_param1 = response.cookies.get('dGg2aCfMMK97Ro270mqBFu5qjC8TQbL2opnHvbEpM', '')
wss_param2 = response.cookies.get('FW9uCWqlVzC22m1KfCMCjfvFHpRMsgt', '')
print(wss_param1, wss_param2)
wss_url = f"wss://www.panzhou.gov.cn/1ywuKELSO2ahQuWZ/pr/{wss_param1}/b/ws/m01j9wq8pw/{wss_param2}" # oiysmb2g7k
print(wss_url)
?然后用wss協(xié)議發(fā)送請(qǐng)求鏈接,接收服務(wù)器響應(yīng)結(jié)果,就能拿到數(shù)據(jù)了,但是卻請(qǐng)求失敗了
import websocket
import _thread as thread
import time
cookie = f'FW9uCWqlVzC22m1KfCMCjfvFHpRMsgt={wss_param2};dGg2aCfMMK97Ro270mqBFu5qjC8TQbL2opnHvbEpM={wss_param1}'
headers2 = {
"Pragma": "no-cache",
"Origin": "https://www.panzhou.gov.cn",
"Accept-Language": "zh-CN,zh;q=0.9",
"Sec-WebSocket-Key": "krDSpbfAbFkDxWiFXTQWxA==",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
"Upgrade": "websocket",
"Cache-Control": "no-cache",
"Cookie": cookie,
"Connection": "Upgrade",
"Sec-WebSocket-Version": "13",
"Sec-WebSocket-Extensions": "permessage-deflate; client_max_window_bits"
}
def on_message(ws, message):
"""收到對(duì)方消息處理方法"""
print("對(duì)方發(fā)來的消息:", "".join(url_unquote(message)))
time.sleep(5) # 控制發(fā)送頻率
ws.send('ping') # 我方?jīng)Q定再回一個(gè)消息
def on_error(ws, error):
""" 錯(cuò)誤處理方法 """
print(error)
def on_close(ws,code,msg):
""" 關(guān)閉處理方法 """
print("代號(hào):",code)
print("對(duì)方關(guān)閉發(fā)來的消息:", msg)
print("### 程序結(jié)束 ###")
def on_open(ws):
""" 運(yùn)行入口 """
def run(*args):
ws.send('ping') # 我方發(fā)送第一個(gè)消息
thread.start_new_thread(run, ()) # 開啟線程
# websocket.enableTrace(True) # 是否打開日志信息
ws = websocket.WebSocketApp(wss_url,
header=headers2, # 設(shè)置請(qǐng)求頭
on_open=on_open, # 設(shè)置運(yùn)行入口
on_message=on_message, # 設(shè)置收到消息處理
on_close=on_close, # 發(fā)生關(guān)閉處理
on_error=on_error, # 錯(cuò)誤處理
)
ws.run_forever()
這個(gè)問題基本上有兩種原因,第一是wss_url不完全正確,第二就是請(qǐng)求頭有其他檢測。而小編已經(jīng)對(duì)可能校驗(yàn)的cookie進(jìn)行處理了,那目前只剩下wss_url的準(zhǔn)確性了。經(jīng)過仔細(xì)觀察鏈接發(fā)現(xiàn),如圖參數(shù)值也是有變動(dòng)的
而該參數(shù)就與上面ajax請(qǐng)求傳參的tabId長度相等,且該值也是變動(dòng)的。那么小編就且將兩者值保持對(duì)應(yīng),再次進(jìn)行wss請(qǐng)求
這次請(qǐng)求就能正常返回?cái)?shù)據(jù)了,結(jié)果如圖
實(shí)戰(zhàn)總結(jié):
js逆向的過程就是這樣,是一個(gè)不斷研究和自我推敲的過程,不過是大佬還是新手小白,都是需要一步一步去入口,定位加密參數(shù),尋找解密方法,完成參數(shù)復(fù)原,模擬正常瀏覽器請(qǐng)求服務(wù)器。所以小編還是希望大家在這個(gè)過程中能不斷嘗試,不斷進(jìn)步文章來源:http://www.zghlxwxcb.cn/news/detail-734378.html
那么,今日的分享就到這里,想要學(xué)習(xí)更多的python爬蟲和js逆向的相關(guān)技巧和知識(shí)的小伙伴們一定要點(diǎn)下關(guān)注喲,后期會(huì)不定時(shí)分享相關(guān)干貨內(nèi)容文章來源地址http://www.zghlxwxcb.cn/news/detail-734378.html
到了這里,關(guān)于WebSocket爬蟲與JS逆向?qū)崙?zhàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!