Johnserf-Seed / TikTokDownload

抖音去水印批量下载用户主页作品、喜欢、收藏、图文、音频
https://github.com/Johnserf-Seed/f2
MIT License
6.42k stars 1.25k forks source link

抖音现在会验证X-bogus #277

Closed zzh151223 closed 1 year ago

zzh151223 commented 1 year ago

网上有教逆向的,但都不分享源码,我自己试直接就卡在第一步了,替换js后断点不生效,所有没办法逆向生成过程。但有个偏方,抖音重写了XMLHttpRequest,那么可以直接在浏览器控制台进行请求,会自动加上mstoken和x-bogus进行请求并返回结果,我现在的方法是使用selenium调用浏览器执行js脚本然后返回数据。

def douYin():
    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    chrome_options = Options()
    # 请求完毕后不关闭页面   在linux上没用,每次执行js前需进入抖音页面
    chrome_options.add_experimental_option('detach', True)
    chrome_options.add_argument('--no-sandbox')
    chrome_options.add_argument('--disable-dev-shm-usage')
    chrome_options.add_argument('--headless')  # 无头模式
    driver = webdriver.Chrome(options=chrome_options)
    # url链接只需附带基本参数即可   这里的url是请求用户信息的,请求主页视频的自己去f12找
    # 我这里的代码意思是检测用户房间号是否为0,不为0则开播了,
    # 并且会出现room_data数据,里面是json字符串含有直播地址等信息,
    # 从中提取出地址然后我后面有其它逻辑进行录制
    script = '''
        var e = {
        'url': 'https://www.douyin.com/aweme/v1/web/user/profile/other/?device_platform=webapp&aid=6383&channel=channel_pc_web&publish_video_strategy_type=2&source=channel_pc_web&sec_user_id=用户web主页id&downlink=10',
        'method': 'GET'};
        var h = new XMLHttpRequest;  // 由于抖音重写了请求逻辑,所以此处直接进行请求即可自动套用重写的请求方法
        h.open(e.method, e.url, false);  // false:同步执行,以免XMLHttpRequest未获取到结果就返回
        h.setRequestHeader('accept', 'application/json; charset=utf-8');
        h.setRequestHeader('salute-by', 'lx');
        var value = '初始值';
        h.onreadystatechange = function(){
        if(h.readyState === 4 && h.status === 200){
        // console.log(h); // h为整个请求的信息  // 如果你们这里请求的是其它数据,以下部分根据实际情况修改
        json = JSON.parse(h.responseText); // 返回的数据,如果你请求主页视频返回的就是主页视频信息
        roomId = json['user']['room_id']; 
        console.log(roomId);  // 直播间房间号
        if (roomId !== 0){
        roomData = JSON.parse(json['user']['room_data']); // 直播间地址信息
        console.log(roomData);
        if (roomData['status'] === 2){
        obj = roomData['stream_url']['flv_pull_url']; // 直播间地址:json格式
        value = obj[Object.keys(obj)[0]]; // 取json第一个值,最高画质
        }else{
        console.log('已开播,但直播间不是公共状态');
        value = 1;
        }
        }else{
        console.log('未开播');
        value = 2;
        }
        }
        };
        h.send(null);
        return value; // 能走到这里value就不可能是初始值了,除非你当前页面不在抖音'''

    # 随便进一个抖音页面,主页会自动播放短视频我这里用的其它页面
    driver.get('https://www.douyin.com/channel/300208')
    # 执行js脚本,如果开播并且直播间为公共状态就返回画质最高的一个直播地址
    # 如果是在linux上执行,最好是每driver.get一次执行一次脚本,
    # 不然页面可能会自动关闭导致请求不会自动附加验证信息,linux上我自己测试时get一次页面最多执行5次脚本
    a = driver.execute_script(script)
    print(a)  # 直播间地址
    driver.close()

douYin()
zzh151223 commented 1 year ago

不知道是不是有抖音工作人员也在逛这里,无头模式被和谐了,不过我又可以了,方法我不透露了,请继续和谐。

fanlushuai commented 9 months ago

nice