本帖最后由 麦田孤望者 于 2020-8-17 11:38 编辑
一、登录
首先打开钉钉网页版https://im.dingtalk.com/
F12,刷新,寻找登录二维码的链接
发现url是base64格式的二维码,于是就打算使用草料看看这个二维码包含的内容
保存——上传草料
可以看到,二维码的链接是由http://qr.dingtalk.com/action/login?code=与code拼成
于是搜索这个code看看能不能找到
可以看到,这个code是GET https://login.dingtalk.com/user/qrcode/generate.jsonp?callback=angular.callbacks._0得到的,验证发现不用带headers
代码实现:
def getCode():
r = self.res.get('https://login.dingtalk.com/user/qrcode/generate.jsonp?callback=angular.callbacks._0')
html = re.findall('\((.*?)\)', r.text, re.S)[0]
callback = json.loads(html)
if callback['success'] == True:
self.Code = callback['result']
self.QRurl = 'http://qr.dingtalk.com/action/login?code='+self.Code
return callback['result']
else:
print('Error01:返回值为否')
获取到了code,就可以构建二维码了
我用的是qrcode
显示图片用的是PIL
代码实现:
[Python] 纯文本查看 复制代码 import qrcode
from PIL import Image
def makeQRcode():
img = qrcode.make(self.QRurl)
with open('test.png', 'wb') as f:
img.save(f)
im = Image.open('test.png')
im.show()
二、获取是否扫码
其实吧,这个借口很容易找到的,毕竟......
就看这个就知道验证接口是它了
接下来分析
headers没什么好分析的
但是带的参数就得好好看一下了
appKey: 85A09F60A599F5E1867EAB915A8BB07F
callback: angular.callbacks._1
pdmModel: Windows Unknown
pdmTitle: Windows Unknown Web
pdmToken: T2gAC1QTLzX2NkrEj6uqt4pP9l_JG61b1WbiRf8_4zBQ0Tsvn922akdPrMjhhuFKaA5bjcPYLgmluUDpj-f2zlgI
qrcode: B5EEC884-3E1B-4B90-8B9B-119062EF68A5
前四个不用管的,都是字面意思
qrcode就是刚才获得到的code
接下来是pdmToken
搜索它生成的位置(我一般先搜值再搜变量名)
在一堆islogged中,我看到了它:um.json
返回的值:
{id: "G28828312008958197E5967600805DC78A7409B"
tn: "T2gAC1QTLzX2NkrEj6uqt4pP9l_JG61b1WbiRf8_4zBQ0Tsvn922akdPrMjhhuFKaA5bjcPYLgmluUDpj-f2zlgI"}
我们要的是返回的tn
于是观察这个请求的参数
data: 106!ECMmc0clJFmH/brVHmjz5Frca5nTQmsm5UamzLHtKj7U5xjMYyoj7K1czEH0n+0MwbLJ3inX9RJvfMbxrO9QayhHTWnC422L3+pmZkGzcPQ6Nw11tV+1mw8Z07GJJ1XX3ycRlqLQH56L5FYhELJY4C1mQpegQ0WRcuE1O4rkysaJPfogzBgMs7DUDWLmrY9BSlngjWCryLAZnCM1U0K5S7kUOHELlT/Q4uDj67/Tr8tvyM2XsQt9gpSUxvXs/ysK42Ujx7/QC0I5YR7XxXcLA8sf82q8VGxIpAKa1R3n8aK08vo0VscQie9YR3gu5M3n069EzUwyOLzrx0N8kQcqZyZ8jytWSDVzna1dMmN4p/eQ5RQ99lMKPHRAWJsKBt6+gQ2imXI8NBnY0pM2fWphO1QppIKk17b+ZaqFIf3gdoJAlRxn6SncJkqUgMagYP8CZAbPhK12Ycu9O7PvX3iRlutz7xcO8RIgzp5B99CVCs7RdPaiNetHNnbxarEj7WmDIhJO1Jvheb10tuR/88pAxLXVboka4OH3mKYSMJLIrYJoKP4EbRFHaxP8S6EyqNHyLrNNxpp+41ilrqpmSkIGaUz2LT52cFlmlSrecfsmcN0FOikY98sEscvfs+yn6faNoIuAEY85NqXuGE/H5dK6qpyVK0lQV6tAv6aUcugh+W+1qJ/J9meqDtLnvGmD4nRLQ+LtExRhOa2NxM52kfwR77Ok2swlgSiHVI52sPsREWCvJnKlYJQe9liFVywMUMyLcubG/aLgUG8U6xx1obuQkgKN
xa: dingding
xt:
data很长 但是经过我大量验证,发现106!是固定的,剩下的一直在变
搜索未果,于是我想知道这个data是不是定值
python重发请求,成功返回数据
于是尝试改变106!后数据,发现只要有106!都可以返回数据
那么就好办了
构造请求um.json
def makedata(self):
data = {
'data':'106!woxiangqiaoni',
'xa':'dingding',
'xt':''
}
r = self.res.post('https://ynuf.aliapp.org/service/um.json',data=data)
_ = r.json()
获得tn
再循环请求https://login.dingtalk.com/user/qrcode/is_logged.jsonp
def checkIfLogined(self):
url = 'https://login.dingtalk.com/user/qrcode/is_logged.jsonp'
params = {
'appKey': '85A09F60A599F5E1867EAB915A8BB07F',
'callback': None,
'pdmModel': 'Windows Unknown',
'pdmTitle': 'Windows Unknown Web',
'pdmToken': self.tn,
'qrcode': self.Code
}
headers = {
'accept': '*/*',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'zh-CN,zh;q=0.9',
'referer': 'https://im.dingtalk.com/',
'sec-fetch-dest': 'script',
'sec-fetch-mode': 'no-cors',
'sec-fetch-site': 'same-site',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36'
}
while True:
r = self.res.get(url,params = params,headers=headers)
_ = json.loads(re.findall('\((.*?)\)',r.text,re.S)[0])
if _['success'] == True:
break
time.sleep(2)
os.remove('test.png')
扫码后获取到了一个json,包含了大量的数据
记住这个json,里面的许多数据后续都很重要
三、获取信息
既然收到消息network页面没有变化,那么应该就是一个websocket连接
连接在long里
前两个请求卡了我一天半
就在求助讨论区发了个贴https://www.52pojie.cn/thread-1240673-1-1.html
(摘要:第一个请求复制message发一遍就行了第二个请求复制下来的message需要手动在headers里补上ua,did,sid,appjey)
did是在long之前的那个请求
那么再看这个请求,带的参数:
code: 127103489********(码一下不确定是不是隐私)********58DE2658appkey: 85A09F60A599F5E1867EAB915A8BB07F
isSession: true
callback: __jp0
搜索code值
那么就在这个json里搜索值
是tmpcode的值
那么至此,did的值就很容易得到了
接下来是sid,sid其实在第一次send信息的时候就返回了,那个在同一个websocket里应该是定值
然后appkey不用讲了吧,定值
搜索token的值,是之前json里的accessToken
ua我复制到的是
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36 OS(windows/10.0) Browser(chrome/84.0.4147.89) DingWeb/3.8.10 LANG/zh_CN
放到headers里就可以了
接下来的内容应该可以更加简单但是我不知道那些是必要的哪些是不必要的
于是我就全部发了一遍.....就这样咯(摊手.jpg)
然后就可以获取信息了
(之前的方法放弃了 我用了一个更简单的方法)接着点开一个群聊,观察数据情况
这个红框部分可以说是相当显眼啊
可以确定,它返回的就是最近的14条消息,0为最新,13为最旧
通过openid可以反推出发送者的信息
过程就不放了 有兴趣的自己尝试(提示:你本人要获取一个人的信息你会怎么操作?)能获取的个人信息很多
{"lwp":"/r/Adaptor/UserMixI/getUserProfileExtensionByUid","headers":{"mid":Mid},"body":[待查openid,null]}
如何识别是否被@
如果被@,则返回数据里会多一个atOpenIds,是个字典,keys就是openid,获取到所有openid后逐个与自己的openid比较即可
再没什么了吧......有的话再问就行
(小声逼逼:不给个币或者给个热心吗,好狠心啊嘤嘤嘤)
写成模块了 见https://github.com/gongxi-cn-ln-dl/DingTalk(留个star再走吧......) |