【爬虫实战】使用Python和JS逆向抖音X-Bogus参数获取N条视频

前言

之前学习了一些JS逆向的知识点,但是都比较初级,基本上只能算是补补JS函数。这次以抖音为例,尝试一下补环境和开发者工具调试断点的新方法。

一、目标分析

1. 筛选接口

首先随机选择一个用户的主页,可以看到有若干作品,目标就是根据用户获取其所有的作品链接,然后下载。

某位UP主的主页

请求的接口有很多,最终筛查出来目标接口:

搜索关键字video可以看到一些URL地址

下载链接

然后访问一下,看看是不是真正的下载链接。

的确,就是这么回事。

2.检查请求头

这里就不再截图了,其实里面没有多少特殊的字段,也就Cookie有点特别。

3. 载荷

这部分有三个字段是密文

至于哪个是决定性的还不知道,也可能是都是必须的,也可能只有某一个。

二、逻辑分析

1. 找到请求入口

肯定先用简单的方式——搜索关键字,不行的话再考虑别的方式。但是这个网站上可以搜索一下X-Bogus,虽然能搜到,但是打过断点后发现并没有走那里。这里不再演示。其他的两个密文字段也一样。

所以最稳妥的方式就是从启动器里查找定位。

发现这里是一个ajax请求,但是可以看到有很多个请求都是从这里发出去的,所以不太好追踪目标接口。但是我们可以使用新的方式来只追踪这个接口:

在这里添加一条,输入目标URL即可,但是要记得先把之前的所有断点都取消。

可以看到自动停在了这里,显示的就是目标URL。

断点

其实在这里的时候,在控制台上输入this,就可以看到XB值已经生成了,在最后面:

1
"/aweme/v1/web/aweme/post/?device_platform=webapp&aid=6383&channel=channel_pc_web&sec_user_id=MS4wLjABAAAAqwlfqpCgGCpMAxMEQm_evPUupsTBamwkG5-s6LWqqOgBTv9tniP-7P6QrjK4-m1N&max_cursor=0&locate_query=false&show_live_replay_strategy=1&need_time_list=1&time_list_query=0&whale_cut_token=&cut_version=1&count=18&publish_video_strategy_type=2&pc_client_type=1&version_code=170400&version_name=17.4.0&cookie_enabled=true&screen_width=1920&screen_height=1080&browser_language=zh-CN&browser_platform=MacIntel&browser_name=Chrome&browser_version=116.0.0.0&browser_online=true&engine_name=Blink&engine_version=116.0.0.0&os_name=Mac+OS&os_version=10.15.7&cpu_core_num=8&device_memory=8&platform=PC&downlink=10&effective_type=4g&round_trip_time=150&webid=7304127941348312585&msToken=m481D4fH-oOr3yUt_GMWxmhIvvFhjoWXQnWK8AK0ZaKuEwbkp-goBkCM5C6N4u03IiMM2JGF064qCIXQjKgQm-SOnXG3OSDbTLhDezOjda_r4pzEL3Fl9MWytJ904EJI&X-Bogus=DFSzswVOcYsANSTItmLIGMm4pIDg"

所以可以检查前一步调用。

进一步追踪

到了这里可以可以确定就是这行生成的密文,但是会发现_0xc26b5e, _0x1f1790这俩值是一直变化的。简单聊一下这里的语法。

1
_0x2458f0['y']++) : _0xcc6308[++_0x2e1055] = _0x2458f0['apply'](_0xc26b5e, _0x1f1790);

apply 是 JavaScript 中的函数方法,用于调用函数,并且可以指定函数执行时的上下文(this 值),以及传递一个数组或类数组对象作为函数的参数。

这行代码中,_0x2458f0['apply'] 表示调用 _0x2458f0 对象的 apply 方法。这个方法的作用是调用一个函数,并且可以将一个数组或类数组对象的元素作为参数传递给这个函数。

具体来说:

  • _0x2458f0: 这是一个对象,可能是一个函数对象。
  • .apply: 这是 JavaScript 函数对象的一个方法,用于调用该函数。
  • _0xc26b5e: 这是一个函数,它将作为 apply 方法的第一个参数传递给 _0x2458f0
  • _0x1f1790: 这是一个数组,它将作为 apply 方法的第二个参数传递给 _0x2458f0 中的函数。

这一行的目的是将 _0x2458f0 对象中的某个函数(可能是函数数组中的某个元素)以 _0xc26b5e 为上下文调用,同时传递 _0x1f1790 数组作为参数,然后将结果赋值给 _0xcc6308[++_0x2e1055]

但是还是不好定位,我们有以下两种方式继续追踪,日志断点和条件断点,首先在_0x2458f0['apply'](_0xc26b5e, _0x1f1790)打断点:日志断点:console.log(_0x2458f0['apply'](_0xc26b5e, _0x1f1790))。输出有很多,但是可以过滤一下关键字,比如URL或者XB的前面的几个字母:

可以看到XB值的确出现了,URL也出现了。接下来可以使用条件断点,当输出XB值的时候断住,再去追踪函数,_0x2458f0['apply'](_0xc26b5e, _0x1f1790).length==28。因为XB值的长度是28位,可以根据这个来判断。

2. 找到加密函数

刷新,然后就被断住了,检查值

然后跟踪函数,可以看到XB值出现了:

返回值

定位结束。

三、代码实现

3.1 JS部分

实现方式有两种,第一种就是补函数,第二种就是补环境。

3.1.1 补函数

首先看第一种,先复制整个文件,然后直接运行。

ReferenceError: window is not defined

增加`window = global``

**ReferenceError: Request is not defined **

定位到代码:

1
2
var _0x2aa7e4 = Request && Request instanceof Object
, _0x2b58b8 = Headers && Headers instanceof Object;

可以看到是两个布尔类型的值,在控制台运行后发现都是true,修改代码:

1
2
var _0x2aa7e4 =true
, _0x2b58b8 = true;

ReferenceError: document is not defined

其实这里提示的是document['referrer'],在控制台或者请求头那里复制一个就行

1
2
3
document = {
"referer":'https://www.douyin.com/user/MS4wLjABAAAAjemOgh7N4uocHHEMmnTrewBlqxuGnVMPr4kVZv6h12s',
}

TypeError: document.addEventListener is not a function

和referer一样,补上即可:

1
2
3
4
document = {
"referer":'https://www.douyin.com/user/MS4wLjABAAAAjemOgh7N4uocHHEMmnTrewBlqxuGnVMPr4kVZv6h12s',
'addEventListener': function addEventListener(){}
}

这时候就会发现不再报错了,那么就可以使用一个全局变量获取XB值了,找到之前加密的函数_0x5a8f25那里。

1
2
3
4
function _0x5a8f25(_0x48914f, _0xa771aa) {
return ('undefined' == typeof window ? global : window)['_$webrt_1668687510']('484e4f4a403f52430017211b45bdadd5a9f8450800000000000007fa1b0002012f1d00921b000b191b000b02402217000a1c1b000b1926402217000c1c1b000b190200004017002646000306000e271f001b000200021d00920500121b001b000b031b000b19041d0092071b000b0401220117000b1c1b000b051e01301700131b00201d00741b000b06260a0000101c1b000b07260a0000101c1b001b000b081e01311d00931b001b000b091e00091d00941b0048021d00951b001b000b1d1d009d1b0048401d009e1b001b000b031b000b18041d00d51b001b000b0a221e0132241b000b031b000b0a221e0132241b000b200a000110040a0001101d00d71b001b000b0a221e0132241b000b031b000b0a221e0132241b000b1a0a000110040a0001101d00d91b000b0b1e00161e01330117002d1b000b0b1e001602000025001d11221e006e24131e00530201340200701a020200000a000210001d01331b001b000b0c1e00101d00da1b000b232217000e1c211b000b23430201353e1700151b001b000b23221e0133240a0000101d00da1b001b000b0d261b000b1c1b000b1b0a0002101d00db1b001b000b0e261b000b241b000b230a0002101d00dd1b001b000b0f261b000b250200200a0002101d00e11b001b000b0a221e0132241b000b031b000b26040a0001101d00e21b001b000b101a00221e00dc240a0000104903e82b1d00e31b001b000b11260a0000101d00e41b001b000b1f1d00e71b001b000b1c4901002b1d00e81b001b000b1c4901002c1d00ea1b001b000b1b1d00ee1b001b000b21480e191d00f31b001b000b21480f191d00f91b001b000b22480e191d00fa1b001b000b22480f191d00fc1b001b000b27480e191d00ff1b001b000b27480f191d01011b001b000b284818344900ff2f1d01021b001b000b284810344900ff2f1d01041b001b000b284808344900ff2f1d01361b001b000b284800344900ff2f1d01371b001b000b294818344900ff2f1d01381b001b000b294810344900ff2f1d01391b001b000b294808344900ff2f1d013a1b001b000b294800344900ff2f1d013b1b001b000b2a1b000b2b311b000b2c311b000b2d311b000b2e311b000b2f311b000b30311b000b31311b000b32311b000b33311b000b34311b000b35311b000b36311b000b37311b000b38311b000b39311b000b3a311b000b3b311d013c1b004900ff1d013d1b001b000b12261b000b2a1b000b2c1b000b2e1b000b301b000b321b000b341b000b361b000b381b000b3a1b000b3c1b000b2b1b000b2d1b000b2f1b000b311b000b331b000b351b000b371b000b391b000b3b0a0013101d013e1b001b000b0e261b000b131b000b3d041b000b3e0a0002101d013f1b001b000b14261b000b1e1b000b3d1b000b3f0a0003101d01401b001b000b15261b000b400200240a0002101d01411b000b4100000142000160203333333333333333333333333333333333333333333333333333333333333333016d0e3130333c3b3005273a253027212c023c31061a373f3036210332302108313037203232302707303b23363a313007363a3b263a393007333c27303720320a3a20213027023c31213d0a3c3b3b3027023c31213d0b3a202130271d303c323d210b3c3b3b30271d303c323d2109202630271432303b210b213a193a223027163426300163073c3b31302d1a33083039303621273a3b09203b3130333c3b30310925273a213a212c253008213a0621273c3b3204363439390725273a36302626100e3a373f3036217525273a3630262608063a373f30362105213c213930043b3a31300168016202266541141716111013121d1c1f1e19181b1a05040706010003020d0c0f343736313033323d3c3f3e39383b3a25242726212023222d2c2f65646766616063626d6c7e7a6802266441113e3125323d610f1e2604176d657a1833232266630d1c640767607e02001439103c621b19373a240c011a05202f38133f1f3b272c2d6c1d03123634062116306802266741113e3125323d610f1e2604176d657a1833232266630d1c640767607802001439103c621b19373a240c011a05202f38133f1f3b272c2d6c1d031236340621163068016c0264640639303b32213d0a363d3427163a3130142102646506363d342714210f0e3a373f30362175023c3b313a220808113a362038303b21120e3a373f303621751b34233c3234213a2708053f26313a38100e3a373f303621751d3c26213a272c0807253920323c3b26080a253d343b213a380b36343939053d343b213a380b0a0a3b3c323d2138342730051420313c3a1816343b23342607303b3130273c3b32163a3b21302d2167110922303731273c233027133230211a223b05273a253027212c1b343830260939343b32203432302606363d273a38300727203b213c383007363a3b3b303621140a0a22303731273c2330270a3023343920342130130a0a263039303b3c20380a30233439203421301b0a0a22303731273c2330270a2636273c25210a33203b36213c3a3b170a0a22303731273c2330270a2636273c25210a33203b36150a0a22303731273c2330270a2636273c25210a333b130a0a332d31273c2330270a3023343920342130120a0a31273c2330270a203b22273425253031150a0a22303731273c2330270a203b22273425253031110a0a31273c2330270a3023343920342130140a0a263039303b3c20380a203b22273425253031140a0a332d31273c2330270a203b22273425253031090a263039303b3c20380c36343939063039303b3c2038160a063039303b3c20380a1c11100a0730363a2731302702646708313a362038303b21043e302c2602646602646102646002646305383421363d06073032102d250a09710e34782f0831360a063634363d300a04263a383008363033063d34272508163033063d34272505303a34253c16303a02303717273a22263027113c26253421363d30270f373c3b311a373f30362114262c3b360e3c26101a02303717273a222630270166043a25303b0421302621093c3b363a323b3c213a073a3b3027273a2704363a31301204001a01140a100d1610101110110a1007070e263026263c3a3b06213a27343230072630211c21303810263a38301e302c1d302730172c2130310a2730383a23301c213038093c3b31302d303111170c053a3c3b2130271023303b210e1806053a3c3b2130271023303b210d36273034213010393038303b210636343b23342609213a1134213400071907273025393436300309267f01320a3b34213c2330363a3130140e3a373f30362175053920323c3b142727342c084a0b3d212125266a6f097a097a7d0e65786c082e647966287d097b0e65786c082e647966287c2e6628290e34783365786c082e647961287d6f0e34783365786c082e647961287c2e62287c016108393a3634213c3a3b043d27303304333c3930103d2121256f7a7a393a3634393d3a26210825393421333a273807223c3b313a222603223c3b07343b31273a3c3105393c3b202d026462063c253d3a3b3002646d043c25343102646c043c253a3102676503383436026764093834363c3b213a263d0c3834360a253a22302725367c0436273a26032d64640536273c3a2605332d3c3a2604253c3e3002676702676602676102676002676302676202676d02676c08333c2730333a2d7a063a253027347a05753a25277a05753a25217a07363d273a38307a0821273c31303b217a0438263c300266650266640623303b313a2706123a3a3239300e0a253427343806223c21363d1a3b0a313c27303621063c323b0a363a3b263c2621303b210626223c21363d03313a3807253d343b213a38043d3a3a3e40141716111013121d1c1f1e19181b1a05040706010003020d0c0f343736313033323d3c3f3e39383b3a25242726212023222d2c2f65646766616063626d6c787b03343c31013b01330127092621342721013c383001210934373c393c213c30260a213c3830262134382564133d34273122342730163a3b36202727303b362c0c3130233c36301830383a272c0839343b32203432300a2730263a3920213c3a3b0f3423343c390730263a3920213c3a3b0926362730303b013a250a26362730303b19303321103130233c3630053c2d30390734213c3a0a25273a31203621062037073734212130272c012509213a20363d1c3b333a08213c38302f3a3b300a213c3830262134382567073225201c3b333a0b3f26133a3b2126193c26210b253920323c3b26193c26210a213c38302621343825660a30233027163a3a3e3c300721210a26363c3101380b262c3b21342d1027273a270c3b34213c233019303b32213d052721361c05093325033027263c3a3b0b0a0a233027263c3a3b0a0a0836393c303b211c310a213c38302621343825610b302d21303b31133c303931042520263d0334393904213d303b093734263063610a363d0c33273a38163d3427163a3130063763610a6665083734263063610a65026667083734263063610a64026666083734263063610a6702666102666002666307323021013c38300266620b313a381b3a210334393c31092620372621273c3b320825273a213a363a3902666d02666c02616502616401650e646565656565656564646565656502616702616607333a272730343902616104373a312c092621273c3b323c332c022e280261600b373a312c033439672621270a373a312c0a3d34263d6801730320273902616305242030272c0a34263a39310a263c323b092534213d3b343830680921210a2230373c3168067320203c316802616202616d0e0a372c2130310a2630360a313c3102616c0a61676c616c6362676c63093330033027263c3a3b0260650e0a656717610f63223a65656565640260640260670526393c3630026066070610161c1b131a033b3a2209213c383026213438250533393a3a270627343b313a380f3230210101023037163a3a3e3c3026052121223c310821210a2230373c310721210230371c310b21210a2230373c310a23670921210230373c3103670727203b3b3c3b3205333920263d08383a2330193c2621062625393c3630063730183a23300936393c363e193c262107373016393c363e0c3e302c373a342731193c26210a37301e302c373a3427310b3436213c233006213421300b223c3b313a2206213421300326013805212734363e08203b3c21013c3830033436360a203b3c2114383a203b210837303d34233c3a2707382632012c253003221c1107343c31193c26210b25273c2334362c183a313006362026213a38063426263c323b0f0210170a1110031c16100a1c1b131a043f263a3b0a2730323c3a3b163a3b33092730253a272100273904302d3c21090d78180678060100170c0d7818067805140c191a141120656565656565656565656565656565656565656565656565656565656565656520316164316d36316c6d33656537676561306c6d65656c6c6d3036336d616762300123062037363a3130063130363a31300421273c38210b0e0926092013101313092d1465087e290e0926092013101313092d1465087e71062621273c3b3202606102606002606302606202606d02606c026365026364026367026366026361026360', [, , void (-0x1afd + 0x22 * 0x25 + 0x1613), void (-0x1 * 0x71e + 0x726 + -0x2 * 0x4) !== _0x38ba41 ? _0x38ba41 : void (0x1 * 0x247f + -0x584 * -0x1 + -0x2a03), void (0x216d + -0x1 * -0x5ba + -0x303 * 0xd) !== _0x3dbe20 ? _0x3dbe20 : void (-0x325 * -0x2 + 0xb1b + -0x49 * 0x3d), void (-0x27 * 0xe9 + -0x19e2 + 0x3d61) !== _0xeb6638 ? _0xeb6638 : void (-0x211a + -0x3d * -0x88 + 0xb2 * 0x1), void (-0x1 * 0x61f + -0x65 * 0x1f + 0x125a) !== _0x2bd2cf ? _0x2bd2cf : void (-0x71e * -0x5 + 0x42b + 0x1 * -0x27c1), void (-0x7 * -0x481 + 0xc49 + -0x2bd0) !== _0x45636f ? _0x45636f : void (-0x1 * 0x1072 + -0x9e4 + 0x1a56 * 0x1), void (0x569 + 0x20ae + 0x571 * -0x7) !== _0x2cee6c ? _0x2cee6c : void (0x6 * 0x10f + -0xac * -0x3a + -0x2d52 * 0x1), void (0x58 * 0x26 + -0x17f6 * 0x1 + -0xa * -0x117) !== _0x402a35 ? _0x402a35 : void (-0x13d4 + 0x1dbd + 0x9e9 * -0x1), void (0x10fb + 0x2332 + -0x342d) !== _0x5cf87b ? _0x5cf87b : void (-0xa * 0x1ed + 0x1713 + 0x3d1 * -0x1), 'undefined' != typeof String ? String : void (-0x1131 + -0x24e8 + 0x1 * 0x3619), 'undefined' != typeof navigator ? navigator : void (0x1 * 0xbdf + -0x173e + 0xb5f), void (-0x3 * 0x166 + -0x584 + 0x9b6) !== _0x5caed2 ? _0x5caed2 : void (-0x10e * -0xf + 0x12b6 + -0x2288), void (0x272 * -0x6 + -0xcf * -0x2f + -0x21 * 0xb5) !== _0x25788b ? _0x25788b : void (-0x9 * -0x37b + -0x1 * 0x143b + -0xb18), void (0x1a77 + -0x53 * -0x16 + -0x2199) !== _0x2642b3 ? _0x2642b3 : void (0x264d + -0x11 * 0x1a + 0x2493 * -0x1), 'undefined' != typeof Date ? Date : void (0x14f * 0x3 + -0x2ff * 0xd + -0x1183 * -0x2), void (-0x1 * 0xb81 + 0x1c8c + -0x110b) !== _0x17dd8c ? _0x17dd8c : void (-0x1 * 0xf01 + -0x466 * -0x5 + 0x6fd * -0x1), void (-0x1 * -0x141b + -0x1 * -0x15ee + -0x2a09) !== _0x398111 ? _0x398111 : void (-0x16bd + 0x1690 + 0x2d), void (0x706 * 0x1 + -0x116 * 0x13 + 0x86 * 0x1a) !== _0x86cb82 ? _0x86cb82 : void (-0x121 + 0x22 * -0xa3 + 0x1 * 0x16c7), void (-0x1 * 0x599 + -0x98a + 0xf23) !== _0x94582 ? _0x94582 : void (-0xa0d + -0x1253 + 0x1c60), void (-0x348 + 0x959 * -0x2 + -0x1d * -0xc2) !== _0x38c772 ? _0x38c772 : void (0x8 * -0x4a2 + -0x6 * 0x340 + -0x10 * -0x389), , _0x5a8f25, _0x48914f, _0xa771aa]);
}
window.xb = _0x5a8f25

最后再输出一下:

1
console.log(window.xb())

TypeError: Cannot read property ‘userAgent’ of undefined

继续补:

1
2
3
navigator = {
"userAgent":'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'
}

再次执行,输出了正常结果,警告部分可以忽视。

输出

3.1.2 补环境

其实这里的补环境,严格意义上还不太算。

首先需要安装vm2:

1
npm install vm2@3.9.3

基础使用

1
2
3
4
5
var vm = require("vm2") // 新的虚拟环境
const {VM, VMScript} = vm
var myvm = new VM() // 新的实例对象
ret = myvm.run("1+2") // 输出 3
ret1 = myvm.run("process") // 会报错,因为在node里是能识别的,但是在vm2这种纯v8环境中是没有的

使用vm2的基本思路如下:

  1. 创建新的虚拟环境,然后实例化
  2. 加载环境相关的JS文件
  3. 加载源码JS文件
  4. 加载特殊函数
  5. 运行并输出返回值。

整体步骤如下:

  1. 首先复制全部的JS代码到一个新文件01,不再重复该步骤具体操作。
  2. 然后创建一个专门用来补环境的JS文件02,之后缺失的东西都写入到这个文件。
  3. 创建运行vm2的JS文件03。

03.js写入以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var fs = require("fs")
var vm = require("vm2")
// 初始化vm对象
const {VM, VMScript} = vm
var myvm = new VM()

jsCode = ""
// (1)添加补环境的代码
code01 = fs.readFileSync("./补环境.js")
// console.log(code01.toString())
jsCode += code01
jsCode += "\n"
// (2)添加源码
code02 = fs.readFileSync("./源码.js")
// console.log(code01.toString())
jsCode += code02
jsCode += "\n"

ReferenceError [Error]: window is not defined

补window到补环境.js,window = global;

ReferenceError [Error]: Request is not defined

补环境.js,

1
2
3
4
Request = function Request() {
}
Headers = function Headers() {
}

ReferenceError [Error]: document is not defined

1
document = {}

ReferenceError [Error]: setTimeout is not defined

1
2
setTimeout = function setTimeout(code, time) {
}

这时候就不再报错了,可以将XB值赋给全局变量了,修改源码,添加window.xb = _0x5a8f25。但是要在源码最后加上一个调用,否则会提示foo不是个函数:

1
window.xb

修改vm环境.js,增加

1
2
3
4
5
6
7
8
9
// (3)执行源码函数
function get_X_B(data) {
var foo = myvm.run(jsCode)
return foo(data)
}

// 测试
data = '123456'
console.log(get_X_B(data))

TypeError [Error]: Cannot read property ‘userAgent’ of undefined

1
2
3
navigator = {
userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36",
}

再次运行就会输出XB值了DFSzs5VOoM2ANSzCtmFkOdsNhy8H

3.2 Python部分

Python部分需要调用返回的XB值发出请求,然后下载文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import execjs
import requests

headers = {
# UA 要和JS代码里的UA保持一致
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36",
"Referer": "https://www.douyin.com/user/MS4wLjABAAAAjemOgh7N4uocHHEMmnTrewBlqxuGnVMPr4kVZv6h12s",
"Cookie": "xxxxxxxx"
}


def start():
with open('xxx.js') as f:
js_code = f.read()
js_compile = execjs.compile(js_code)
params = f'device_platform=webapp&aid=6383&channel=channel_pc_web&sec_user_id={user_id}&max_cursor=0&locate_query=false&show_live_replay_strategy=1&need_time_list=1&time_list_query=0&whale_cut_token=&cut_version=1&count=18&publish_video_strategy_type=2&pc_client_type=1&version_code=170400&version_name=17.4.0&cookie_enabled=true&screen_width=1512&screen_height=982&browser_language=zh-CN&browser_platform=MacIntel&browser_name=Chrome&browser_version=116.0.0.0&browser_online=true&engine_name=Blink&engine_version=116.0.0.0&os_name=Mac+OS&os_version=10.15.7&cpu_core_num=8&device_memory=8&platform=PC&downlink=10&effective_type=4g&round_trip_time=250&webid=7304127941348312585&msToken=cuOiVLmw388t-pv_8HmGuvMpvRPH70MzpRJrPHOLxp9d8hP4_G08a9mxgOg37OJFtjmrh1tGi763daipLCOjS3JKutS9LmM5K6HfiF1tCHYir31g4Up9rOP-F6BQyR_n&X-Bogus=DFSzswVutpbANSBUtmbP4lm4pIdL'
xb = js_compile.call("window.xb", params)
print(xb)
url = 'https://www.douyin.com/aweme/v1/web/aweme/post/?'
new_url = url + params + "&X-Bogus=" + xb
resp = requests.get(new_url, headers=headers)
print(resp.json())


if __name__ == '__main__':
# user_id = 'MS4wLjABAAAAjemOgh7N4uocHHEMmnTrewBlqxuGnVMPr4kVZv6h12s'
user_id = 'MS4wLjABAAAAMbqnWxzUfZegt9vrNBDz7zyqwhvG6vXiKTDxVm2wUD0'
start()

这样就实现了视频地址的获取,如果想要下载也很简单,直接requests请求即可,没啥难度。这里只是展示了获取单个用户的作品,稍微修改一下就可以获取更多用户的作品。

此外还有个翻页的问题,之前的代码只能获取第一页。是否有下一页取决于响应数据中的has_more的值是否为1,和之前的小红书是一样的,如果为1就继续循环。

首次请求

首次请求max_cursor为0,响应数据为1698056089000。

响应数据

那么下次的max_cursor就是刚才数据里的1698056089000。规律就是首次请求值为0,下次请求的值为上一次的返回的max_cursor。

就是这么回事。

以上代码较为简陋,后来又解决了一系列的问题:

  1. 翻页
  2. 获取多个用户的视频
  3. 批量下载

如果有更多问题,可以联系我。

四、总结

首先逆向了XB值,使用了基础版的补环境方式,学习了打断点的另外两种方式。之后分析了视频列表翻页的问题。