FBI WARNING
具体脚本可以参考
https://bbs.tampermonkey.net.cn/thread-872-1-1.html
前言
之前我们已经学习了xhr劫持的姿势
现在我们来实战一下,通过xhr劫持直接拿到返回的内容
通常通过xhr劫持可以达成两种效果,一个是在xhr发送数据之前对数据进行获取和篡改,一个则是在xhr返回数据之后进行获取
我们可以在https://www.douyin.com/user/MS4wLjABAAAAeq80JKa1oaIFOCOFjkw8o5STIHIsAnBQxVPxVJ4C7RZ5Hn8f1d_zNsMKaa8EOlCw?enter_method=video_title&author_id=3395719513245832&group_id=6976849455186185505&log_pb=%7B%22impr_id%22%3A%22021629423215634fdbddc0100fff0030a1217e00000001a54c1a3%22%7D&enter_from=undefined
通过f12进行抓包
大概查看一下数据,发现在https://www.douyin.com/aweme/v1/web/aweme/post/?device_platform=webapp&aid=6383&channel=channel_pc_web&sec_user_id=MS4wLjABAAAAeq80JKa1oaIFOCOFjkw8o5STIHIsAnBQxVPxVJ4C7RZ5Hn8f1d_zNsMKaa8EOlCw&max_cursor=1624424355000&count=10&publish_video_strategy_type=2&version_code=160100&version_name=16.1.0&cookie_enabled=true&screen_width=1536&screen_height=864&browser_language=zh-CN&browser_platform=Win32&browser_name=Mozilla&browser_version=5.0+(Windows+NT+10.0%3B+Win64%3B+x64)+AppleWebKit%2F537.36+(KHTML,+like+Gecko)+Chrome%2F92.0.4515.159+Safari%2F537.36&browser_online=true&_signature=_02B4Z6wo00d01gP1vzgAAIDCg.dFeeve9RYD9buAAOHw7d
中的awemelist疑似是获取到的链接,这种乱七八糟一堆东西,我们想要做到解密是极其麻烦的,所以我们在这里可以直接打出一个xhr劫持获取返回内容
在这个网页里我们通过获取video的视频链接可以得到是v26开头的前缀,所以我们找一个json在线格式化的工具,贴入数据并解析,搜索v26
https://www.sojson.com/
发现很多地方都是存在v26链接的,挑几个进行测试,我最后找到了video.play_addr.url_list是无水印的链接
所以这里就打出了一个xhr劫持
function addXMLRequestCallback(callback){
var oldSend, i;
if( XMLHttpRequest.callbacks ) {
// we've already overridden send() so just add the callback
XMLHttpRequest.callbacks.push( callback );
} else {
// create a callback queue
XMLHttpRequest.callbacks = [callback];
// store the native send()
oldSend = XMLHttpRequest.prototype.send;
// override the native send()
XMLHttpRequest.prototype.send = function(){
// process the callback queue
// the xhr instance is passed into each callback but seems pretty useless
// you can't tell what its destination is or call abort() without an error
// so only really good for logging that a request has happened
// I could be wrong, I hope so...
// EDIT: I suppose you could override the onreadystatechange handler though
for( i = 0; i < XMLHttpRequest.callbacks.length; i++ ) {
XMLHttpRequest.callbacks[i]( this );
}
// call the native send()
oldSend.apply(this, arguments);
}
}
}
// e.g.
addXMLRequestCallback( function( xhr ) {
xhr.addEventListener("load", function(){
if ( xhr.readyState == 4 && xhr.status == 200 ) {
if(xhr.responseURL.indexOf('/web/aweme/post')!==-1){
console.log('触发了加载')
let list=JSON.parse(xhr.response)
if(list.aweme_list!==undefined){
for(let index=0;index<list.aweme_list.length;index++){
let item=list.aweme_list[index].video.play_addr.url_list
if(item.length!==0){
videolist.push('https://'+item[0].replace('https://','').replace('http://','').replace('//',''))
}else{
alert('888')}
}
}
}
}
});
});
由于他是一个数组,所以这里判断了是否不为0再进行传入
('https://'+item[0].replace('https://','').replace('http://','').replace('//',''))
因为一些存在前缀,一些不存在http前缀,一些前缀是//,所以我这里直接全部过滤为空加入了https
那这里我们的抖音视频解析就完成了一半了,大家如果测试会发现
刚进入页面是没有进行这个post的
这个是为什么呢?
因为很多网页在加载过程中,会把一些用户数据或者页面数据直接放入网页中,在加载的过程中直接渲染
所以我才会推荐大家没思路的时候看看网页源代码进行分析
这里我们搜索v26看到了存在一个script标签,里面有一大坨乱七八糟的数据
看到%22%3A%221579877069082637%22%2C%22hashtagName%22%3A%22%E4%B8%
这种乱七八糟的%字符串,通常是url编码,我们需要进行解码
let unrender=JSON.parse(decodeURIComponent(document.querySelector('#RENDER_DATA').innerText))
编码与解码的方式通常存在三种
escape 和 unescape
encodeURI 和 decodeURI
encodeURIComponent 和 decodeURIComponent
通常我们使用decodeURIComponent就可以了
在解码之后成了一个文本,我们通过json.parse进行解码,因为他是一个对象进行字符化的文本
我们平时通过json对对象进行文本化以及将文本化转换成对象
言归正传
解析成对象的unrender存在三个键值,其中只有一个是存在视频列表的,所以我们使用Object.keys(unrender)获取他的所有键值
并且用for进行遍历
for(let index=0;index<keys.length;index++){
if(unrender[keys[index]].post!==undefined){
GetRenderTextVideo(videolist,unrender[keys[index]].post.data)
}
}
如果对应的对象的键值内存在post属性,就调用GetRenderTextVideo函数
function GetRenderTextVideo(MergeArray,VideoList){
for(let index=0;index<VideoList.length;index++){
let item=VideoList[index].video.playAddr
if(item.length!==0){
MergeArray.push('https://'+item[0].src.replace('//',''))
}else{
alert('8887')}
}
}
这里的对象与我们通过xhr获取的对象不太一致,但是如何找到免水印的字符串的方法基本一致
到这里我们就完成了xhr的获取实战,下节课我们学习如果修改xhr参数!
结语
撒花~