吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 56081|回复: 984
上一主题 下一主题
收起左侧

[Web逆向] 手撕某解析网站,获取真实播放地址(保姆级讲解)

    [复制链接]
跳转到指定楼层
楼主
youxii52 发表于 2022-2-20 23:33 回帖奖励
一、声明

本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除!

二、前言

最近追上了电视剧,为了方便自己,准备去抓几个接口,于是就度娘一下,除了广告还有这个么多,很好,那我们就拿排名第一的分析分析,文才不佳,还请各位将就着


三、目标

主页:dHYuaHp3ZGQuY24=

接口:aHR0cHM6Ly9qeC5wYXJ3aXguY29tOjQ0MzMvcGxheWVyL2FuYWx5c2lzLnBocD92PWh0dHBzOi8vdi5xcS5jb20veC9jb3Zlci96cjVhNjdsMzMzZWh6dTkuaHRtbA==

四、无限debugger

F12打开控制台后,会进入一个无限debugger,为了我们以后的调试,我们不得不将它干掉



我们回溯到这里,发现调用 setInterval 方法,该方法可按照指定的周期(以毫秒计)来调用函数或计算表达式,
很明显,它调用了check,注意check函数,是将debugger 传递给了构造方法constructor,所以这里hook掉constructor



我们打开fiddler,开启hook代码如下
[JavaScript] 纯文本查看 复制代码
Function.prototype.constructor_ = Function.prototype.constructor;
Function.prototype.constructor = function (a) {
if(a == "debugger") {
return function (){};
}
return Function.prototype.constructor_(a);
};




五、抓包分析
ok,我们干掉了烦人的无限debugger,我们抽取接口地址:

aHR0cHM6Ly9qeC5wYXJ3aXguY29tOjQ0MzMvcGxheWVyL2FuYWx5c2lzLnBocD92PWh0dHBzOi8vdi5xcS5jb20veC9jb3Zlci96cjVhNjdsMzMzZWh6dTkuaHRtbA==
重新加载一篇,很明显视频可以正常播放,而且我们的目标播放地址也能看到了



接下来我们分析播放地址是怎么来的,我们用接口地址访问,整个页面非常简单,我们看看接口地址返回了什么




一个加密的视频地址,一个加密混淆的abc函数代码


ok,我们来看看abc函数

[JavaScript] 纯文本查看 复制代码
function abc(){
        ["sojson.v4"]["\x66\x69\x6c\x74\x65\x72"]["\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72"](((["sojson.v4"]+[])["\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72"]

["\x66\x72\x6f\x6d\x43\x68\x61\x72\x43\x6f\x64\x65"]["\x61\x70\x70\x6c\x79"]

(null,"118M97i114L32C95D112e114M32G61l32C36A40O39B109e101w116m97N91Y110y97I109I101J61q34E118i105N101h119R112I111G114T116z34Z93o39m41o46S97o116b116T114C40Q39r105I100m39O41f46U1

14P101B112t108d97g99M101X40Z39P118u111s100A95O39A44e39g39J41Y59l10b32j32e32e32l32Q32n32f32t32a118D97w114r32U95V112F117z32K61r32u36G40g39d109N101d116S97V91d99M104m97q114M115y10

1f116h61K34w85c84X70z45j56J34p93O39e41V46G97P116a116d114P40O39i105B100S39x41s46l114Y101I112E108w97m99h101q40y39Q118Y111A100D95p39V44X39z39a41k59d10l32M32v32d32n32C32G32G32y32Y

118K97O114u32v95f112e117z65W114w114y32i32f61T32Y91i93E59x10x32v32T32e32F32b32U32r32a32i118t97z114A32W95U110r101v119r65O114i114Q32O61b32E91L93N59u10R32u32A32c32y32R32I32o32Y32W

118A97L114D32l95E99E111W100P101N32D32N32o61n32d39r39Q59g10e32K32g32w32X32k32b32j32p32A10r32X32X32r32U32D32j32q32F32v102U111D114X40g118e97v114V32B105N61c48U59v105z60L32m95z112Z

117S46y108a101b110K103a116h104H59O32A105Z43o43m41Y123Q10e32c32v32B32G32E32J32a32W32t32O32J32s32j10C32T32K32A32I32A32h32Z32V32J32T32b32C32A95X112e117z65C114t114M46Z112J117P115l

104d40w123z32e39j105C100S39Q58a95S112I117K91j105n93t44k32P39w116Q101p120K116x39p58p32R95z112D114A91S105Z93U32x125Q41J59i10H32c32l32G32D32r32A32R32L32G125F10Q32h32M32W32j32E32Y

32m32J32P10L32v32y32A32C32t32U32B32F32B47D47G23545R23494p38053e37325J26032k36827g34892u25490S24207C10x32l32G32B32d32m32E32i32u32i95d110c101L119a65o114y114k32C61p32k95Y112l117v

65w114h114i46w115f111r114A116X40T80Z65Q82U46v99c111s109f112g97f114p101g40q34x105x100U34i41e41i59J10a32U32m32y32y32X32s32K32W32P10J32V32H32w32E32x32U32Q32s32M102B111V114Y40j118

e97h114K32v105L61J48h59d105G60A32g95B110Z101F119J65v114x114v46B108c101j110g103W116R104F59f32a105p43b43f41b123o10Q32Z32I32J32e32A32m32k32r32p32b32Q32W32G10P32J32H32T32F32V32U32

V32g32W32p32A32n32W95q99w111Y100k101e43b61C95A110p101v119I65k114F114V91d105G93N91D39y116d101X120u116H39t93a59b10h32Z32D32E32F32S32K32D32a32l125J10O32P32n32b32c32K32u32S32b32u9

9t111x110K102Q105h103D46T117p114L108l32q61u32t32H80X65I82r46Q115H101x99D114Y101a116V40C99c111I110h102K105f103X46Q117N114w108E44f32f95U99b111W100R101a44L32u116U114P117q101I41w5

9"["\x73\x70\x6c\x69\x74"](/[a-zA-Z]{1,}/))))("sojson.v4");


我们先把字符串编码解决一下,大概就是这个样子
[JavaScript] 纯文本查看 复制代码
['sojson.v4']+[])["constructor"]['fromCharCode']['apply'](null,"123456..."['split'](/[a-zA-Z]{1,}/))))['sojson.v4']

根据个人理解,上面几乎可以等于以下代码

[JavaScript] 纯文本查看 复制代码
''.constructor.fromCharCode.apply(null,"123456...".split(/[a-zA-Z]{1,}/))

大概意思就是把"123456..."转换成字符数组“1”“2”...,然后用fromCharCode方法转换成字符串

[JavaScript] 纯文本查看 复制代码
String.fromCharCode(“1”“2”...)

我们在控制台输出一下



ok,我们得到如下字符串代码

[JavaScript] 纯文本查看 复制代码
(function anonymous(
) {
var _pr = $('meta[name="viewport"]').attr('id').replace('vod_','');
         var _pu = $('meta[charset="UTF-8"]').attr('id').replace('vod_','');
         var _puArr  = [];
         var _newArr = [];
         var _code   = '';
         
         for(var i=0;i< _pu.length; i++){
             
             _puArr.push({ 'id':_pu[i], 'text': _pr[i] });
         }
         
         //对密钥重新进行排序
         _newArr = _puArr.sort(PAR.compare("id"));
         
         for(var i=0;i< _newArr.length; i++){
             
             _code+=_newArr[i]['text'];
         }
         config.url =  PAR.secret(config.url, _code, true);
})


我们分析分析,获取接口地址返回pr和pu,然后组装成puArr数组,对puArr通过PAR.compare方法按照id大小重新排序,
然后得到_code,然后通过PAR.secret方法,传入页面加密的url和_code和true
得到一个新的url,这里,我们大胆一点,新的url应该就是真实播放地址



ok,流程理清楚了,现在关键的就是PAR.compare和PAR.secret这2个函数了

我们全文模糊搜索PAR  PAR:PAR= var PAR等关键字,很快就定位到尾号为676f.js里




五、OB混淆
我们不难发现,整个尾号为676f.js是一个混淆代码,我们拷贝下来,分析分析




开头定义了一个大数组,然后对这个大数组里的内容进行位移,再定义一个解密函数。后面大部分的值都调用了这个解密函数,以达到混淆的效果。
这个就是传说中的OB混淆我们先看看PAR.compare和PAR.secret

[JavaScript] 纯文本查看 复制代码
'compare': function(_0x209a13) {
        var _0x2b0a5b = {
            'hupwx': function(_0x28592c, _0x5c0aae) {
                return _0x28592c - _0x5c0aae;
            }
        };
        return function(_0x4490c6, _0x47bde8) {
            var _0x11d139 = _0x4490c6[_0x209a13];
            var _0x2b383f = _0x47bde8[_0x209a13];
            return _0x2b0a5b[_0x15b4('6e', 'yYg5')](_0x11d139, _0x2b383f);
        }


'secret': function(_0x141a71, _0x433196, _0x45cf51) {
        var _0x20b4ff = {
            'bCQqZ': _0x15b4('6f', 'xfLW'),
            'hAcOs': _0x15b4('70', 'wHsA')
        };
        _0x433196 = CryptoJS[_0x15b4('71', 'p5&!')](_0x433196)['toString']();
        var _0x4f0cf6 = CryptoJS['enc'][_0x15b4('72', 'a]Oa')][_0x15b4('73', 'Knq)')](_0x433196['substring'](0x0, 0x10));
        var _0x1030c4 = CryptoJS['enc'][_0x15b4('74', 'eKXt')]['parse'](_0x433196['substring'](0x10));
        if (_0x45cf51) {
            if (_0x20b4ff[_0x15b4('75', 'eKXt')] !== 'vLPSI') {
                return CryptoJS[_0x15b4('76', 'AIBX')][_0x15b4('77', 'tzTY')](_0x141a71, _0x1030c4, {
                    'iv': _0x4f0cf6,
                    'padding': CryptoJS[_0x15b4('78', 'I0@(')]['Pkcs7']
                })['toString'](CryptoJS['enc'][_0x15b4('79', 'vNOA')]);
            } else {
                PAR[_0x15b4('7a', 'wHsA')]['post_r'](a, b, c, d, _0x20b4ff[_0x15b4('7b', 'xB(L')]);
            }
        }
        return CryptoJS[_0x15b4('7c', 'bVZ)')][_0x15b4('7d', 'Bb3L')](_0x141a71, _0x1030c4, {
            'iv': _0x4f0cf6,
            'mode': CryptoJS[_0x15b4('7e', 'vzyU')][_0x15b4('7f', 'Ya)8')],
            'padding': CryptoJS[_0x15b4('80', 'jX$g')][_0x15b4('81', 'xB(L')]
        })[_0x15b4('82', 'OZnY')]();
    }


看样子混淆程度不高,一些关键字眼我们还是可以认出来,比如说CryptoJS,我们可以选择动态调试硬钢
不过,我还是选择把它还原一下,本地慢慢分析。
我们刚讲了,尾号为676f.js为标准的OB混淆样式,解密函数很明显就是_0x15b4,更何况PAR.compare和
PAR.secret多处调用,我们只需要把尾号为676f.js的前三段提取出来运行一遍,就能得到类似于_0x15b4('6e', 'yYg5')的值
这里可以选择硬钢替换,也可以选着用AST还原



不过需要注意的是这里有个暗坑,此段代码会检测你是否格式化,如果格式化了,就会内存爆破,进去无限循环,直到浏览器崩溃,有兴趣的同学可以试试





简单还原一下,然后PAR.compare和PAR.secret就成了这个样子
[JavaScript] 纯文本查看 复制代码
'compare': function (_0x209a13) {
    var _0x2b0a5b = {
      'hupwx': function (_0x28592c, _0x5c0aae) {
        return _0x28592c - _0x5c0aae;
      }
    };
    return function (_0x4490c6, _0x47bde8) {
      var _0x11d139 = _0x4490c6[_0x209a13];
      var _0x2b383f = _0x47bde8[_0x209a13];
      return _0x2b0a5b["hupwx"](_0x11d139, _0x2b383f);
    };
  },
  'secret': function (_0x141a71, _0x433196, _0x45cf51) {
    var _0x20b4ff = {
      'bCQqZ': "\u8D4C\u535A\u8BC8\u9A97",
      'hAcOs': "LSEHx"
    };
    _0x433196 = CryptoJS["MD5"](_0x433196)['toString']();

    var _0x4f0cf6 = CryptoJS['enc']["Utf8"]["parse"](_0x433196['substring'](0x0, 0x10));

    var _0x1030c4 = CryptoJS['enc']["Utf8"]['parse'](_0x433196['substring'](0x10));

    if (_0x45cf51) {
      if ("LSEHx" !== 'vLPSI') {
        return CryptoJS["AES"]["decrypt"](_0x141a71, _0x1030c4, {
          'iv': _0x4f0cf6,
          'padding': CryptoJS["pad"]['Pkcs7']
        })['toString'](CryptoJS['enc']["Utf8"]);
      } else {
        PAR["danmu"]['post_r'](a, b, c, d, "\u8D4C\u535A\u8BC8\u9A97");
      }
    }

    return CryptoJS["AES"]["encrypt"](_0x141a71, _0x1030c4, {
      'iv': _0x4f0cf6,
      'mode': CryptoJS["mode"]["CBC"],
      'padding': CryptoJS["pad"]["Pkcs7"]
    })["toString"]();
  },


先看PAR.compare,我们发现就是sort的排列方式函数,我们改写一下
[JavaScript] 纯文本查看 复制代码
function compare(d){
  function hupwx(a, b) {
      return a - b;
  }
  
  return function (a1, b1) {
    var a = a1[d];
    var b = b1[d];
    return hupwx(a, b);
  };
}


至于PAR.secret,细心的童鞋已经发现他是调用加解密库(crypto-js)进行的一个AES解密,我们也改写一下

[JavaScript] 纯文本查看 复制代码
function secret (url, _bcode) {
      
    code = CryptoJS["MD5"](_bcode)['toString']();

    var _0x4f0cf6 = CryptoJS['enc']["Utf8"]["parse"](code['substring'](0x0, 0x10));

    var _0x1030c4 = CryptoJS['enc']["Utf8"]['parse'](code['substring'](0x10));
 
    return CryptoJS["AES"]["decrypt"](url, _0x1030c4, {
        'iv': _0x4f0cf6,
        'padding': CryptoJS["pad"]['Pkcs7']
        })['toString'](CryptoJS['enc']["Utf8"]);
} 


几个重要的参数'iv','padding',key清新可见

我们来梳理一下,前面我们说了对puArr通过PAR.compare方法重新排序,然后得到_code,然后传入加密url和_code,
通过md5加密得到code,取code前16位得到IV,取后16位得到key,最后decrypt解密成明文url
因此我们改写一下abc函数,全局搜索CryptoJS,拿到尾号为cd51.js,稍微改写一下来验证一下(当然这里直接调用crypto-js加解密库也是一样)


需要注意,每次请求接口地址url和pr/pu都要变化,为了方便我们暂时先固定一下

[JavaScript] 纯文本查看 复制代码
function abc(){
    
           //var _pr = $('meta[name="viewport"]').attr('id').replace('vod_','');
           //var _pu = $('meta[charset="UTF-8"]').attr('id').replace('vod_','');
           var _pr ="vod_dQb7shnQWf".replace('vod_','');
           var _pu ="vod_5318769240".replace('vod_','');

           var _puArr  = [];
           var _newArr = [];
           var _code   = '';
           var url="a7GlmXWmVruOTAcF8VaB3idxA924haXMwKMPzu7dl0NDlQQVrqVTZwUvzFj8KRYjkthOjRXHwPtT86kzfj46WVnIA3DbSmBfQEE2ICd3OI2FBhOfcRauLNQ2kSxcrRlDOl8R6wY3q7tG6xBA0k

+Drs/iZFbc/llpLEyk06vOMkdt/3qxWxazor5E6mIvJ0PoieCvj9FJoooWECzXOiWgMBIX0EmKw5o4zWWRipLZTXdo69bbSFUJ1PphkS50snOkvdtzh1uKd2xTKqERLC

+iOTqRvBz8YtqjashI5MW0yhhkboK8StIK2QUIa0AACQBDJfhk3bxkmLyW8zdFBZa5iRfW5BNcq3DulkpKK8wY/+c40wesKygPXgBpgultR82yZmPCMHXrxDpxJDDywKXhYauH/iYyGO05V

+2pLMx6i9Biaq6XUPluh2VsMUe7GjWE1cKneEkmyJw4bMB23YY9Rr0RrV4gzoQ08xT+n2LeLsOKU4APkXuVEIKLXx+Wgo5SzpWqJL5N4MahNRpcetHavjoynwvCX1Mh59U4U67x5TKan8a9hO4209Qvc+0n

+fWxWjYZ0erlgTrxvlwU1EVQeRincA0jI0DF5tVtErYxs90="; 
           for(var i=0;i< _pu.length; i++){
               
               _puArr.push({ 'id':_pu[i], 'text': _pr[i] });
           }
           
           //对密钥重新进行排序
           
           
           _newArr = _puArr.sort(compare("id"));
           console.log(_newArr);
           for(var i=0;i< _newArr.length; i++){
               
               _code+=_newArr[i]['text'];
           }
           
           url1 =  secret(url, _code);
           
           return url1;
}          


测试OK,至此播放地址拿到手了



以下附上js源码和简单的AST源码,如果对AST感兴趣,我们下次再聊

链接:https://pan.baidu.com/s/1hni_Usg861uuznfVPmVOJg
提取码:52pj

源码.7z

44.99 KB, 下载次数: 23, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 396吾爱币 +362 热心值 +347 收起 理由
CHEN_zuhe + 1 + 1 鼓励转贴优秀软件安全工具和文档!
云中君88 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
VAN666666 + 1 + 1 用心讨论,共获提升!
windpeaceflowe + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
kapod + 1 + 1 我很赞同!
xiaoxinya + 1 + 1 谢谢@Thanks!
RUO + 1 + 1 谢谢@Thanks!
5omggx + 1 + 1 用心讨论,共获提升!
jiejie123 + 1 我很赞同!
chengdragon + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
1DMC1 + 1 用心讨论,共获提升!
hjg145 + 1 收藏了,有机会再试
q99 + 1 + 1 谢谢@Thanks!
FJFJ + 1 + 1 用心讨论,共获提升!
shaohejiu + 1 我很赞同!
hannoch + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
z1129 + 1 + 1 我很赞同!
ABuSiDeLuoYin + 1 + 1 我已经看懵了
motong + 1 + 1 谢谢@Thanks!
abc520670 + 1 我很赞同!
ldd123 + 1 我很赞同!
invisible_m + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
fridax + 1 + 1 我很赞同!
张男 + 1 + 1 用心讨论,共获提升!
ff123 + 1 我很赞同!
_逛窑子 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
18121376836 + 1 + 1 我很赞同!
谁在等我 + 1 + 1 热心回复!
心比天傲 + 1 + 1 我很赞同!
ghimi + 1 用心讨论,共获提升!
wlk1996618 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
chenzhehan521 + 1 我很赞同!
pojie_dd + 1 我很赞同!
procurve + 1 + 1 谢谢@Thanks!
hxiang + 1 我很赞同!
guyong + 1 + 1 我很赞同!
simon77 + 1 用心讨论,共获提升!
leee0609 + 1 + 1 我很赞同!
HYan + 1 + 1 我很赞同!
tianjuenb + 1 我很赞同!
jason30 + 1 + 1 我很赞同!
niu916 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
annye + 1 用心讨论,共获提升!
z0905 + 1 + 1 我很赞同!
Sophons + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
红海豚 + 1 + 1 谢谢@Thanks!
兮忘沃 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
xinjun_ying + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
weizhimubiao + 1 热心回复!
weixu + 1 + 1 谢谢@Thanks!
leweishang + 1 我很赞同!
tqh13673752510 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
wangyufei19 + 1 谢谢@Thanks!
sanyuebeichen + 1 热心回复!
mouccc + 1 + 1 热心回复!
ColdZ + 1 + 1 我很赞同!
Tunx + 1 + 1 谢谢@Thanks!
jackies + 1 + 1 热心回复!
yangwei + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
MatrixLau + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
Rubindai + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
p52p + 1 + 1 我很赞同!
xxbc123 + 1 + 1 谢谢@Thanks!
EchoY + 1 + 1 谢谢@Thanks!
Y.S. + 1 用心讨论,共获提升!
BryanNorton + 1 + 1 用心讨论,共获提升!
Yoke123 + 1 + 1 我很赞同!
cugnan + 1 + 1 用心讨论,共获提升!
Y1zh1ma0 + 1 很牛
jalor + 1 + 1 谢谢@Thanks!
g486520 + 1 厉害了
zxj1997 + 1 我很赞同!
daniel882 + 1 用心讨论,共获提升!
huowang88 + 1 + 1 用心讨论,共获提升!
code917 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
brIckZ + 1 热心回复!
qch + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
taoge888 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
DaiCap + 1 + 1 用心讨论,共获提升!
Leaf02 + 1 + 1 我很赞同!
liuyumo + 1 + 1 我很赞同!
15866082026 + 1 + 1 厉害了我的哥收藏学习
mumuwhb + 1 + 1 我很赞同!
45402130 + 1 + 1 谢谢@Thanks!
lrm6066 + 1 谢谢@Thanks!
404undefined + 1 + 1 我很赞同!
luiskuan + 1 + 1 谢谢@Thanks!
GGY2022 + 1 我很赞同!
xsytf + 1 + 1 谢谢@Thanks!
ranminnice + 1 + 1 我很赞同!
zs777 + 1 + 1 我很赞同!
chris0106 + 1 + 1 我很赞同!
xktl + 1 看不懂但大震撼
tingguo + 1 热心回复!
fengchenlu + 1 我很赞同!
SHFKUGO + 1 我很赞同!
151219mjy + 1 + 1 我很赞同!
LonelyCrow + 1 + 1 用心讨论,共获提升!
solofuc + 1 + 1 我很赞同!
vgh5332 + 1 用心讨论,共获提升!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
sa123456sc 发表于 2022-2-24 14:15

[Asm] 纯文本查看 复制代码
 @Autowired(required = false)
    private MovieService movieService;


    @Autowired(required = false)
    private MovieEpisodeService movieEpisodeService;

    /**
     * [url=home.php?mod=space&uid=952169]@Param[/url] @throws Exception
     */
    public void refreshTvFromTx() throws Exception {
        Map<String,Object> movieMap=new HashMap<String,Object>();
        movieMap.put("movieType","2");//电视剧
        movieMap.put("source",source);//腾讯视频
        movieMap.put("isOver","0");//未完成
        List<Movie> movies = movieService.list(movieMap);
        for(Movie movie:movies){
            getTvFromTx(TxUrl,movie);
        }
    }

    /**
     * 从腾讯获取电视剧
     * @param TxUrl  电视剧ID
     * @param movie
     */
    public int getTvFromTx(String TxUrl,Movie movie){
        int count = 0;
        HttpRequest httpRequest=new HttpRequest();
        String webPageContent=httpRequest.getHTMLContentByHttpGetMethod(TxUrl.replaceAll("TVID",movie.getTvId()),"UTF-8");
        if("".equals(webPageContent)){
            logger.info("腾讯电视剧网页获取失败!");
        }else{
            Movie currentMovie = new Movie();
            Map<String,Object> movieMap=new HashMap<String,Object>();
            movieMap.put("tvId",movie.getTvId());
            if(movieService.getTotal(movieMap)>0){//已经存在
                currentMovie = movieService.list(movieMap).get(0);
            }else{
                currentMovie = movie;
                currentMovie.setUuId(UUID.randomUUID().toString());
                currentMovie.setClick(0);
                currentMovie.setOrderNo(movieService.getMaxOrderNo());
                currentMovie.setEnabled("1");
                currentMovie.setMovieType("2");
                currentMovie.setIsTop("0");
                currentMovie.setIsOver("0");
                count += movieService.add(currentMovie);//添加进电影主表
            }
            if(currentMovie.getIsOver().equals("0")){//未更新完
                Document document= Jsoup.parse(webPageContent);
                Element titleTV = document.getElementsByClass("mod_figure_detail mod_figure_detail_en cf").get(0);//标题部分
                currentMovie.setMoviePicPath(titleTV.getElementsByClass("figure_pic").get(0).attr("src"));
                currentMovie.setMovieName(titleTV.getElementsByAttributeValue("_stat","info:title").text());
                currentMovie.setMovieScore(titleTV.getElementsByClass("score_v").get(0).getElementsByClass("score").text());
                if(titleTV.getElementsByClass("mark_pic").size() > 0){
                    currentMovie.setMovieTag(titleTV.getElementsByClass("mark_pic").get(0).attr("src"));
                }
                currentMovie.setMovieDesc(titleTV.getElementsByClass("txt _desc_txt_lineHight").get(0).text());
                currentMovie.setTvDesc(titleTV.getElementsByClass("txt _desc_txt_lineHight").get(0).text());
                currentMovie.setEpisodeCount(Integer.parseInt(titleTV.getElementsMatchingOwnText("总集数:").get(0).nextElementSibling().text()));
                //-----------------------每集内容---------------------------//
                Element episodes =  document.getElementsByClass("mod_episode").get(0);
                Elements episode = episodes.getElementsByClass("item");
                for(int i = 0; i<episode.size();i++){
                    if(episode.get(i).getElementsByClass("mark_v").size()==0){//没有vip标志,直接写进数据库
                        int episodeNo = Integer.parseInt(episode.get(i).getElementsByTag("a").get(0).getElementsByTag("span").get(0).text());
                        Map<String,Object> movieEpisodeMap=new HashMap<String,Object>();
                        movieEpisodeMap.put("movieId",currentMovie.getUuId());
                        movieEpisodeMap.put("episodeNo",episodeNo);
                        if(movieEpisodeService.getTotal(movieEpisodeMap)<1){
                            MovieEpisode movieEpisode =new MovieEpisode();
                            movieEpisode.setUuId(UUID.randomUUID().toString());
                            movieEpisode.setMovieId(currentMovie.getUuId());
                            movieEpisode.setEpisodeUrl(episode.get(i).getElementsByTag("a").get(0).attr("href"));
                            movieEpisode.setEpisodeNo(episodeNo);
                            count += movieEpisodeService.add(movieEpisode);
                            if(movieEpisode.getEpisodeNo()==1){//第一集放到主页
                                currentMovie.setMovieUrlPath(movieEpisode.getEpisodeUrl());
                            }
                        }

                    }else{
                        if(episode.get(i).getElementsByClass("mark_v").get(0).getElementsByClass("mark_pic").get(0).attr("alt").contains("预")){
                        }else{
                            int episodeNo = Integer.parseInt(episode.get(i).getElementsByTag("a").get(0).getElementsByTag("span").get(0).text());
                            Map<String,Object> movieEpisodeMap=new HashMap<String,Object>();
                            movieEpisodeMap.put("movieId",currentMovie.getUuId());
                            movieEpisodeMap.put("episodeNo",episodeNo);
                            if(movieEpisodeService.getTotal(movieEpisodeMap)<1){
                                MovieEpisode movieEpisode =new MovieEpisode();
                                movieEpisode.setUuId(UUID.randomUUID().toString());
                                movieEpisode.setMovieId(currentMovie.getUuId());
                                movieEpisode.setEpisodeUrl(episode.get(i).getElementsByTag("a").get(0).attr("href"));
                                movieEpisode.setEpisodeNo(episodeNo);
                                count += movieEpisodeService.add(movieEpisode);
                                if(movieEpisode.getEpisodeNo()==1){//第一集放到主页
                                    currentMovie.setMovieUrlPath(movieEpisode.getEpisodeUrl());
                                }
                            }
                        }

                    }

                }
                //-----------------------每集完毕之后更新主记录---------------------------//
                Map<String,Object> map=new HashMap<String,Object>();
                map.put("movieId",currentMovie.getUuId());
                if(currentMovie.getEpisodeCount().intValue()==movieEpisodeService.getMaxNo(map).intValue()){
                    currentMovie.setMovieTime(movieEpisodeService.getMaxNo(map)+"集(全)");
                    currentMovie.setIsOver("1");
                }else{
                    currentMovie.setMovieTime(movieEpisodeService.getMaxNo(map)+"/"+currentMovie.getEpisodeCount()+"集(更新中)");
                    currentMovie.setIsOver("0");
                }
                movieService.updateByClass(currentMovie);
            }
        }
        return count;
    }

免费评分

参与人数 4吾爱币 +3 热心值 +4 收起 理由
XIAOHUANGDI520 + 1 + 1 用心讨论,共获提升!
AfricanTiger + 1 + 1 谢谢@Thanks!
xl02582 + 1 用心讨论,共获提升!
greydesolate + 1 + 1 我很赞同!

查看全部评分

推荐
 楼主| youxii52 发表于 2022-2-22 09:20 |楼主
a147888123 发表于 2022-2-21 21:27
大佬那个fidder 和hook得插件提供下地址可以吗

fidder可以去官网下,这个是志远大佬的插件地址https://share.weiyun.com/EiZcTy8S

免费评分

参与人数 7吾爱币 +5 热心值 +6 收起 理由
616118 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
hsly177 + 1 热心回复!
xiaotiao857 + 1 热心回复!
起飞了 + 1 用心讨论,共获提升!
wuaikirin + 1 + 1 我很赞同!
theseye + 1 + 1 我很赞同!
tail88 + 1 + 1 谢谢@Thanks!

查看全部评分

推荐
sa123456sc 发表于 2022-2-23 14:32
不明觉厉,跟着大佬的例子,一步一步走,在第二步就被拦下了。我自己也用java写了一个网站,定时任务爬取最新电影,电视剧,主要是给自己看的。方法是调用的解析接口。这个方法有个弊端,解析接口在手机电脑上都能正常播放,在自家电视上却被屏蔽了,应该是接口的某个函数给阻止了。本来想跟着大佬获取到真实地址就能实现在电视上看片了,看来是学不会了。
推荐
JUNE3546 发表于 2022-2-21 15:28
马克一下,太好的图文。
推荐
fhwhite 发表于 2022-2-21 16:25
mark,先存后学,底子差需要一点点抠才能看懂些
4#
xiayusammr 发表于 2022-2-21 15:29
很细,连我这样的都看得懂一点,但是好久没摸了,手生。
5#
老滑稽 发表于 2022-2-21 15:36
牛批啊,先收藏,有时间试试
6#
penz 发表于 2022-2-21 15:48
学习了,好!
7#
judgecx 发表于 2022-2-21 15:55
woc 好强的感觉 只看懂了返回接口
8#
5552692 发表于 2022-2-21 15:57
厉害了我的哥收藏学习
9#
弗由 发表于 2022-2-21 16:17
好厉害的大佬
10#
我今天是大佬 发表于 2022-2-21 16:47
学习了, 感谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-23 02:55

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表