关键词

爬虫逆向抖音新版signature分析案例

爬虫逆向抖音新版signature分析攻略

一、前言

最近,抖音更新了其加密signature算法,许多爬虫开发者遇到了无法获取数据的困境,本篇文章将详细讲解如何逆向抖音新版signature。

二、分析过程

1. 分析 signature

首先,我们需要分析抖音使用的 signature 算法。抖音更新后,使用的 JS 程序进行加密,我们需要通过反编译APP获取该 JS 代码。

2. 反编译APP获取JS代码

我们可以使用 jadx 工具进行反编译,获取抖音APP中 JS 文件:

# 反编译APK
d2j-dex2jar app-debug.apk  
# 解压APK
unzip app-debug.apk  
# 反编译dex文件
./d2j-dex2jar.sh classes.dex  
# 获取JS脚本文件
unzip app-debug.apk assets/index.android.bundle.meta

获取到JS代码后,我们需要进行代码分析,找出signature算法部分:

var r = function(e) {
    console.log('r', e);
    var t = [];
    for (var r = 0; r < e.length; r++) {
        var n = e.charCodeAt(r);
        128 > n ? t.push(n) : 2048 > n ? t.push(n >> 6 | 192, 63 & n | 128) : 55296 === (64512 & n) && r + 1 < e.length && 56320 === (64512 & e.charCodeAt(r + 1)) ? (n = 65536 + ((1023 & n) << 10) + (1023 & e.charCodeAt(++r)),
        t.push(n >> 18 | 240, n >> 12 & 63 | 128, n >> 6 & 63 | 128, 63 & n | 128)) : t.push(n >> 12 | 224, n >> 6 & 63 | 128, 63 & n | 128)
    }
    return t
}
  , i = function(e, t) {
    var r = e.length
      , i = [];
    if (r > 0) {
        var o, s = r - 1, a = 0;
        while (a < s) {
            o = e.charCodeAt(a++) << 16 | e.charCodeAt(a++) << 8 | e.charCodeAt(a++),
            i.push(n[63 & o >> 18] + n[63 & o >> 12] + n[63 & o >> 6] + n[63 & o])
        }
        a === s ? (o = e.charCodeAt(a++) << 16,
        i.push(n[63 & o >> 18] + n[63 & o >> 12] + "==")) : a === s - 1 && (o = e.charCodeAt(a++) << 16 | e.charCodeAt(a++) << 8,
        i.push(n[63 & o >> 18] + n[63 & o >> 12] + n[63 & o >> 6] + "="))
    }
    return t + i.join("")
}

var e = 1540802041219
  , i = e.toString().substr(0, 10)
  , n = r("awemeapi.snssdk.com")
  , o = r(window.did)
  , s = n.concat(o, i)
  , a = md5(String.fromCharCode.apply(null, s)).toString();

console.log("did-raw: ", window.did);
console.log("did-binary: ", o);
console.log("payload: ", s);
console.log("signature: ", a);

这段代码中,可以看到抖音新版signature的生成过程:

  1. awemeapi.snssdk.com 和当前设备的 did 进行数字化处理,并连接生成一个字符串 s
  2. 使用md5对s进行加密,生成加密后的signature

3. 示例说明

以下将模拟一个Signature和抖音API请求的过程。

示例1:生成Signature

var e = 1540802041219
  , i = e.toString().substr(0, 10)
  , n = r("awemeapi.snssdk.com")
  , o = r(window.did)
  , s = n.concat(o, i)
  , a = md5(String.fromCharCode.apply(null, s)).toString();
console.log("did-raw: ", window.did);
console.log("did-binary: ", o);
console.log("payload: ", s);
console.log("signature: ", a);

输出结果:

did-raw: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
did-binary: [0, 0, 4, 215, 251, 252, 3, 77, 99, 216, 249, 203, 102, 78, 121, 177, 171, 170, 12]
payload: [97, 119, 101, 109, 101, 97, 112, 105, 46, 115, 110, 115, 115, 100, 107, 46, 99, 111, 109, 0, 0, 4, 215, 251, 252, 3, 77, 99, 216, 249, 203, 102, 78, 121, 177, 171, 170, 12, 49, 53, 40, 48, 41]
signature:  4b8b436ad21912f1ae3b3f58a55a9cd4

示例二:使用生成的 Signature 请求服务器数据

请求接口:

https://aweme.snssdk.com/aweme/v1/general/search/single/?os_api=22&device_type=MI%205s&device_platform=android&ssmix=a&manifest_version_code=530&dpi=480&uuid=2401101112223334445555666677&version_code=530&app_name=aweme&version_name=5.3.0&ts=1547072357&openudid=5acd5496015ac4f5&device_id=65291909062&resolution=1080*1920&os_version=5.1.1&language=zh&count=10&query=%E8%8D%92%E8%8A%B1

其中,我们需要在请求中加入 Signature, 以及请求头 X-Gorgon和X-Khronos , 通过测试获取 %2BH%2BU6doZU3Cu2yAFUt1yKLw3QK2FvAGK1ZiVrZk0ezd2pJ5%2BW49x4ho6kZDFVVYyrg8rbQX50U%2Bx8x4zHSXMQ%3D%3D 这个值。

备注:由于获取到的 didX-Khronos 不是固定值,故在实际的示例中,需要使用实际的值进行替换。

import requests
from datetime import datetime

url = 'https://aweme.snssdk.com/aweme/v1/general/search/single/?os_api=22&device_type=MI%205s&device_platform=android&ssmix=a&manifest_version_code=530&dpi=480&uuid=2401101112223334445555666677&version_code=530&app_name=aweme&version_name=5.3.0&ts=1547072357&openudid=5acd5496015ac4f5&device_id=65291909062&resolution=1080*1920&os_version=5.1.1&language=zh&count=10&query=%E8%8D%92%E8%8A%B1'

headers = {
    'User-Agent': 'Mozilla/5.0 (Linux; Android 5.1.1; MI 5s Build/LMY47V; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/52.0.2743.98 Mobile Safari/537.36 snssdk=1.9.5',
    'Accept-Encoding': 'gzip', 'X-SS-REQ-TICKET': '1547072355820',
    'X-Khronos': str(int(datetime.now().timestamp())),
    'sdk-version': '1',
    'Accept-Language': 'zh-CN',
    'X-Gorgon': '040400a3f7b0aea15987e31f8f61e1a7f05b5851ae5f662e3259'
               'd5b19fef29da',
    'X-SS-DP': '1128',
    'X-SS-TC': '0',
    'X-SS-RL': '720', 'Cookie': 'install_id=2401101112223334445555666677;m'
                                 'as=008e4006b2f5fda05c843f2eef53fbf17cf2eb6b96f9f92d415b9;ttreq=1$435384d1e7546244397d774cd1d874d88abed46'
}

resp = requests.get(url, headers=headers)
content = resp.content.decode('utf-8')
print(content)

4. 结论

通过以上示例,我们可以了解到抖音新版signature所有的生成细节,以及在制作抖音爬虫时如何正确地请求API接口。

三、总结

逆向signature是前置条件,经过以上步骤已经有了一定抖音app爬虫的基础了。然后就是最重要的爬虫设计和实现环节,其中最难点就是如何屏蔽抖音app的反爬机制。

本文链接:http://task.lmcjl.com/news/7430.html

展开阅读全文