温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

网易云音乐热评爬虫中怎么用python实现反编译加密参数

发布时间:2021-12-08 11:45:03 阅读:170 作者:小新 栏目:云计算
Python开发者专用服务器限时活动,0元免费领,库存有限,领完即止! 点击查看>>

小编给大家分享一下网易云音乐热评爬虫中怎么用python实现反编译加密参数,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

一、了解加密过程

    1.1 通过观察网络请求

        发现如下接口包含所要的数据。包含该页最新评论,以及所有热评

     网易云音乐热评爬虫中怎么用python实现反编译加密参数

    再看它评论的参数,着实让人有点懵逼

    网易云音乐热评爬虫中怎么用python实现反编译加密参数

  很多人看见这一串字符,可能简单看下前后接口有没数据就放弃了。好了,不卖关子。这章分析下整个参数的加密过程,实现最终模拟请求拿到数据。

 1.2 找请求参数

     可以看的到,它的参数有两个,一个是params,一个是encSecKey并且都是经过加密的,我们就要分析它在js中的位置F12打开source搜索encSecKey)

    网易云音乐热评爬虫中怎么用python实现反编译加密参数

     进入js内部,经过断点调试发现这里就是生成最终参数的地方

    1.3 观察参数变化

    模拟不同分页请求,观察变化。效果如下图:

网易云音乐热评爬虫中怎么用python实现反编译加密参数

对比参数变化,得出参数构成:

  • csrf_token :始终空字符串

  • cursor :第一页默认-1;请求下一页时该参数为上一页最后一条评论时间戳(防止数据重复)

  • offset :移动评论数

  • orderType :默认1

  • pageNo :页码

  • pageSize :默认20

  • rid : R_SO_4_  + 歌曲ID

  • threadId : R_SO_4_  + 歌曲ID

自此,我们已经知道整个参数的构成,接下来就看下网易云是如何进行参数加密的

二、分析加密函数

            通过断点已经知道,下面这段js代码为我们分析的重点

          var bZj0x = window.asrsea(JSON.stringify(i2x), bkk0x(["流泪""强"]), bkk0x(YS7L.md), bkk0x(["爱心""女孩""惊恐""大笑"]));
            e2x.data = j2x.cr3x({
                params: bZj0x.encText,
                encSecKey: bZj0x.encSecKey
            })

           只要把bZj0x解出来就ok了,这里主要分析几个函数

        2.1  JSON.stringify(i2x)

        断点调制找到i2x返回内容

网易云音乐热评爬虫中怎么用python实现反编译加密参数

就是上文分析的整个字典参数

csrf_token: ""
cursor: "1610076350235"
offset: "40"
orderType: "1"
pageNo: "2"
pageSize: "20"
rid: "R_SO_4_1807537867"
threadId: "R_SO_4_1807537867"

 2.2 bkk0x函数

 bkk0x(["流泪", "强"]), bkk0x(YS7L.md), bkk0x(["爱心", "女孩", "惊恐", "大笑"]),都用到了同一个函数,这里就看下bkk0x函数内部实现是怎样的

var bkk0x = function(cJj8b) {
        var m2x = [];
        j2x.bf2x(cJj8b, function(cJi8a) {
            m2x.push(YS7L.emj[cJi8a])
        });
        return m2x.join("")
    }

等同于python写法

def get_bq_n1x(keys):
    m0x = []
    for key in keys:
        m0x.append(emj[key])
    return ''.join(m0x)

    YS7L.emj是一个固定的字典

YS7L.emj = {
        "色""00e0b",
        "流感""509f6",
        "这边""259df",
        "弱""8642d",
        "嘴唇""bc356",
        "亲""62901",
        "开心""477df",
        "呲牙""22677",
        "憨笑""ec152",
        "猫""b5ff6",
        "皱眉""8ace6",
        "幽灵""15bb7",
        "蛋糕""b7251",
        "发怒""52b3a",
        "大哭""b17a8",
        "兔子""76aea",
        "星星""8a5aa",
        "钟情""76d2e",
        "牵手""41762",
        "公鸡""9ec4e",
        "爱意""e341f",
        "禁止""56135",
        "狗""fccf6",
        "亲亲""95280",
        "叉""104e0",
        "礼物""312ec",
        "晕""bda92",
        "呆""557c9",
        "生病""38701",
        "钻石""14af6",
        "拜""c9d05",
        "怒""c4f7f",
        "示爱""0c368",
        "汗""5b7a4",
        "小鸡""6bee2",
        "痛苦""55932",
        "撇嘴""575cc",
        "惶恐""e10b4",
        "口罩""24d81",
        "吐舌""3cfe4",
        "心碎""875d3",
        "生气""e8204",
        "可爱""7b97d",
        "鬼脸""def52",
        "跳舞""741d5",
        "男孩""46b8e",
        "奸笑""289dc",
        "猪""6935b",
        "圈""3ece0",
        "便便""462db",
        "外星""0a22b",
        "圣诞""8e7",
        "流泪""01000",
        "强""1",
        "爱心""0CoJU",
        "女孩""m6Qyw",
        "惊恐""8W8ju",
        "大笑""d"
    }

   YS7L.md是一个固定的数据

YS7L.md = ["色""流感""这边""弱""嘴唇""亲""开心""呲牙""憨笑""猫""皱眉""幽灵""蛋糕""发怒""大哭""兔子""星星""钟情""牵手""公鸡""爱意""禁止""狗""亲亲""叉""礼物""晕""呆""生病""钻石""拜""怒""示爱""汗""小鸡""痛苦""撇嘴""惶恐""口罩""吐舌""心碎""生气""可爱""鬼脸""跳舞""男孩""奸笑""猪""圈""便便""外星""圣诞"]

所以整个window.asrsea的参数都是可以得到的了,下面看下 window.asrsea()查看这个函数执行了什么操作

2.3 window.asrsea()

function a(a) {
        var d, e, b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", c = "";
        for (d = 0; a > d; d += 1)
            e = Math.random() * b.length,
            e = Math.floor(e),
            c += b.charAt(e);
        return c
    }
    function b(a, b) {
        var c = CryptoJS.enc.Utf8.parse(b)
          , d = CryptoJS.enc.Utf8.parse("0102030405060708")
          , e = CryptoJS.enc.Utf8.parse(a)
          , f = CryptoJS.AES.encrypt(e, c, {
            iv: d,
            modeCryptoJS.mode.CBC
        });
        return f.toString()
    }
    function c(a, b, c) {
        var d, e;
        return setMaxDigits(131),
        d = new RSAKeyPair(b,"",c),
        e = encryptedString(d, a)
    }
    function d(d, e, f, g) {
        var h = {}
          , i = a(16);
        return h.encText = b(d, g),
        h.encText = b(h.encText, i),
        h.encSecKey = c(i, e, f),
        h
    }
    function e(a, b, d, e) {
        var f = {};
        return f.encText = c(a + e, b, d),
        f
    }
    window.asrsea = d

可以看到window.asrsea = d,所以我们要执行的就是d这个函数,主要执行3个操作

  1. a(16),生成16位随机数

  2. 进行两次AES加密得到h.encText

  3. 通过位移等一系列运算生成h.encSecKey

三、Python实现相同的加密算法

"""
网易云请求参数反编译工具
    :主要断点观察js,改为python实现
"""

emj = {
    "色""00e0b",
    "流感""509f6",
    "这边""259df",
    "弱""8642d",
    "嘴唇""bc356",
    "亲""62901",
    "开心""477df",
    "呲牙""22677",
    "憨笑""ec152",
    "猫""b5ff6",
    "皱眉""8ace6",
    "幽灵""15bb7",
    "蛋糕""b7251",
    "发怒""52b3a",
    "大哭""b17a8",
    "兔子""76aea",
    "星星""8a5aa",
    "钟情""76d2e",
    "牵手""41762",
    "公鸡""9ec4e",
    "爱意""e341f",
    "禁止""56135",
    "狗""fccf6",
    "亲亲""95280",
    "叉""104e0",
    "礼物""312ec",
    "晕""bda92",
    "呆""557c9",
    "生病""38701",
    "钻石""14af6",
    "拜""c9d05",
    "怒""c4f7f",
    "示爱""0c368",
    "汗""5b7a4",
    "小鸡""6bee2",
    "痛苦""55932",
    "撇嘴""575cc",
    "惶恐""e10b4",
    "口罩""24d81",
    "吐舌""3cfe4",
    "心碎""875d3",
    "生气""e8204",
    "可爱""7b97d",
    "鬼脸""def52",
    "跳舞""741d5",
    "男孩""46b8e",
    "奸笑""289dc",
    "猪""6935b",
    "圈""3ece0",
    "便便""462db",
    "外星""0a22b",
    "圣诞""8e7",
    "流泪""01000",
    "强""1",
    "爱心""0CoJU",
    "女孩""m6Qyw",
    "惊恐""8W8ju",
    "大笑""d"
}

md = ["色""流感""这边""弱""嘴唇""亲""开心""呲牙""憨笑""猫""皱眉""幽灵""蛋糕""发怒""大哭""兔子""星星""钟情""牵手",
      "公鸡""爱意""禁止""狗""亲亲""叉""礼物""晕""呆""生病""钻石""拜""怒""示爱""汗""小鸡""痛苦""撇嘴""惶恐""口罩",
      "吐舌""心碎""生气""可爱""鬼脸""跳舞""男孩""奸笑""猪""圈""便便""外星""圣诞"]


def get_bq_n1x(keys):
    m0x = []
    for key in keys:
        m0x.append(emj[key])
    return ''.join(m0x)


def __get_random_str():
    """
    Returns:16位的随机字符串

    """
    str_set = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    random_str = ""
    for i in range(16):
        index = random.randint(0len(str_set) - 1)
        random_str += str_set[index]
    return random_str


arg2 = get_bq_n1x(["流泪""强"])
arg3 = get_bq_n1x(md)
arg4 = get_bq_n1x(["爱心""女孩""惊恐""大笑"])
random_str = __get_random_str()


def __aes_encrypt(text, key):
    """
    获取到ASW加密后的数据
    Args:
        text: 首先CBC加密方法,text必须位16位数据
        key: 加密的key

    Returns:加密后的字符串

    """
    # 加密或者解密的初始向量(16位)
    iv = "0102030405060708"
    # 不是16的倍数则填充
    pad = 16 - len(text) % 16
    if isinstance(text, str):
        text = text + pad * chr(pad)
    else:
        text = text.deocde("utf-8") + pad * chr(pad)
    aes = AES.new(key=bytes(key, encoding="utf-8"), mode=2, iv=bytes(iv, encoding="utf-8"))
    res = aes.encrypt(bytes(text, encoding="utf-8"))
    res = base64.b64encode(res).decode("utf-8")
    return res


def __get_enc_text(arg1):
    """
    对称加密后的参数
    Args:
        arg1:加密参数

    Returns:

    """
    enc_text = __aes_encrypt(arg1, arg4)
    enc_text = __aes_encrypt(enc_text, random_str)
    return enc_text


def __get_enc_sec_key():
    """
    对称加密密钥

    通过查看js代码,获取encSecKey
    """

    #  随机字符串逆序排列
    text = random_str[::-1]
    rs = int(codecs.encode(text.encode('utf-8'), 'hex_codec'), 16) ** int(arg2, 16) % int(arg3, 16)
    return format(rs, 'x').zfill(256)


def linux_encrypt(text):
    # print(text)
    return text


def get_form_data(text, method=''):
    """
    反编译生成
    请求的form-data参数
    Args:
        text: 跟踪js,自己组装参数
        method: 方法

    Returns:form-data参数

    """
    """
    
    """
    if method == 'linux':
        return linux_encrypt(text)
    text = str(text)

    return {"params": __get_enc_text(text), "encSecKey": __get_enc_sec_key()}

四、模拟请求歌曲评论

 只要加密过程知道了,其实很多接口都可以模拟请求,此文仅供学习。

最终执行效果如下图:

网易云音乐热评爬虫中怎么用python实现反编译加密参数

以上是“网易云音乐热评爬虫中怎么用python实现反编译加密参数”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

原文链接:https://my.oschina.net/u/2963821/blog/4885034

AI

开发者交流群×