网站怎么做统计,做静态网站需要什么,房产信息查询系统官方网站,磐安做网站Python模拟websocket登陆-拆包封包 解析一个网站获取wss原始数据拆包wss数据封包wss数据发送接收websocket的常驻后台脚本总结 解析一个网站
这里所用的网站是我一个内测的网站#xff0c;主要手段是chrome devtools#xff0c;用得很多#xff0c;但我玩的不深#xff0c… Python模拟websocket登陆-拆包封包 解析一个网站获取wss原始数据拆包wss数据封包wss数据发送接收websocket的常驻后台脚本总结 解析一个网站
这里所用的网站是我一个内测的网站主要手段是chrome devtools用得很多但我玩的不深这次上了点干货.
首先在网络那一块找到js或者index.html右键点击选择替换内容在需要分析的地方写上自己的代码。对于ajax加载的js模块把js在加载地址换成离线下载到本地的地址存入本地的服务原来是http的还还用http。原来https的必须也在https本地web开启跨域允许。然后ajax加载部分js也就替换成可定制的了。虽然代码很难读但是在适合的地方可以随便写cosole.log.对于js的调试和中断不太懂还没用界面的记录器标签可以记录一组点击然后能看到json代码用于回放。记录的动作可以用js实现插入在任何位置只要调试通过就行。
获取wss原始数据
获取数据的两种方式各种优缺点
在上一章中可以看到websocket建立和sendBytesonMessage之类的函数在这里启动cosole.log就能得到逐条纪录。不论ws还是wss。这里可以看到语义并可定制测试代码。在devtools网络标签下的wss://server:port/url地址对应的respone可以取得全部的来往数据和代码块所收发的字节按道理是完全一致的可以做为一个验证和参考。
拆包wss数据
所谓的拆包是理解数据的意义我还没有修炼到靠数据读含义的深度只能靠代码也就js顺眼化处理的代码比如以下的登陆数据代码从1万行里拽出来的。
消息头4表字节 u.prototype.addHeader function(e, t, n, a) {return void 0 n (n 0),void 0 a (a 0),e | t 4 | n 12 | a 23
4个参数在长度 e-4bit, t -,8bit,n-11bit a-9bit. 含义ecommand ,taction, nlength,aext
登陆消息的主体 var a new z.SyncLogonDto;a.account e.account,a.sn e.sn,a.token e.token,a.uid e.userID,a.localHost 0,4 a.sn.length 0 a.uid ! a.token ? this.sendMsg(a.getBody(), z.ServiceType.HALL_CMD, z.ServiceType.HALL_LOGIN_ACT, 2 o.prototype.getBody function() {var e new t.BGByteArray;return e.writeUnsignedInt(this.major),e.writeUnsignedInt(this.minor),e.writeUTFBytes(this.sn),e.writeUnsignedInt(this.localHost),e.writeLongUint(this.uid),var a new z.SyncLogonDto;a.account e.account,a.sn e.sn,a.token e.token,a.uid e.userID,a.localHost 0,4 a.sn.length 0 a.uid ! a.token ? this.sendMsg(a.getBody(), z.ServiceType.HALL_CMD, z.ServiceType.HALL_LOGIN_ACT, 2 o.prototype.getBody function() {var e new t.BGByteArray;return e.writeUnsignedInt(this.major),e.writeUnsignedInt(this.minor),e.writeUTFBytes(this.sn),e.writeUnsignedInt(this.localHost),e.writeLongUint(this.uid),e.writeFixedLenthString(this.account, 32),e.writeFixedLenthString(this.token, 32),e},a o,t.SyncLogonDto ae.writeFixedLenthString(this.token, 32),e},a o,t.SyncLogonDto a主要的处理逻辑在·o.prototype.getBody function() 这里的writeUnsigedInt是四字节无符号整数而且是小头的。就是低位在前高位在后相同还有 writeFixedLenthString(this.account, 32),补充位也是先写入数据后填充‘\x00’,在python的bytes使用bytes.ljust(后面有详细介绍。
这是消息的主体
封包wss数据
根据上面在js可以生成一些python代码用于数据组织
def addHeader(bodyl,command,action0,ext0):# Data---\x3e command: t action: n size: 4len(e),ext:anum command | action 4 | bodyl 12 | ext 23#num.to_bytes(length32,byteorderlittle)return num.to_bytes(length4,byteorderlittle)def parseHeader(hex411c08500):# little_byte b\x01\x00\x00\x00\x00\x00\x00\x00hex4int.from_bytes(bytes.fromhex(hex4),byteorderlittle)commandhex4 int(F,16)actionhex44 int(FF,16)lhex412 int(7FF,16) #only 11bitexthex423 print (fcommand:{command},action:{action},len:{l},ext:{ext})def loginbytes(sn,lh,uid,account,token):rebytes()reint(b01,16).to_bytes(4,byteorderlittle)reint(b01,16).to_bytes(4,byteorderlittle)resn.encode()reint(lh).to_bytes(4,byteorderlittle)reint(uid).to_bytes(8,byteorderlittle)reaccount.encode().ljust(32,b\x00)retoken.encode().ljust(32,b\x00)# print(len(re))# print (re.hex())return re解释 addHeader使用按位或在返回时byteorderlittle)这是比较原始数据得出的。 parseHeader用按位与移位来排除前与来排除后只留对照有用的。 这两个函数处理4字节32位的头部信息。 loginbytes 是改写的js中的SyncLogonDto getBody其中account.encode().ljust(32,b\x00)是对account补足32int(uid).to_bytes(8,byteorderlittle)是将uid转为长整数8字节长低位在前高位在后的bytes。
发送接收websocket的常驻后台脚本
本段代码pip install websocket-client 版本号1.18websocket协议13
import websocket
import threading
import time
import os
import login
#os.path[../]
# 定义当接收到消息时调用的回调函数
def on_message(ws, message):print(fReceived message: {message})# 定义当连接关闭时调用的回调函数
def on_close(ws, close_status_code, close_msg):print(f### Closed ###)# 定义当出现错误时调用的回调函数
def on_error(ws, error):print(f### Error ### {error})if __name__ __main__:# websocket服务地址ws_service_address ws://your_websocket_serverws_service_address wss://alidr-311.klwgt.com/data# 创建websocket应用实例websocket.enableTrace(True)ws websocket.WebSocketApp(ws_service_address,on_messageon_message,on_closeon_close,on_erroron_error)# 创建一个线程用于运行websocket客户端wst threading.Thread(targetws.run_forever)wst.daemon Truewst.start()time.sleep(3)msslogin.getlogin()ws.send_bytes(mss)# 主线程做其他事情...# 例如主线程可以发送消息到websocket服务器# ws.send(Your message here)# 主线程在此处等待否则程序会立即退出# 如果你的程序需要在后台运行则不需要这一行wst.join()其实主要就是来自百度AI的一段代码。稍加调整假入了延时的登陆调用。然后就成功登陆了。实现和浏览器js登陆websocket的一样的效果。
总结
虽然这段代码没有什么业务功能细节也是基本的类型转换但是它是从怀疑中不断产生的。因为我开始时怀疑python在websocket库是否能完全仿真js在websocket。在查看js的建立连接的请求头时发现协议版本是2011年的13然后查看了websocket-client在pypi也是支持到这个版本只是还没有实现gzip功能的扩展。 既然如此wss的 建立也没要求cookie和其实token。那就用python跑一下。基于开始处对于网站数据的整理要是没有原本的js脚本这也是一个不可能完成的事情了。但是虽然登陆成了以后的业务逻辑还不知道怎么处理。最少分步骤实现批处理是可以的。这就由python建立 了 一个js代码的客户端。 好吧纯属有病。 再见