爬虫加密解密学习总结

本文详细介绍了如何使用Python爬取网易云音乐的评论信息,包括理解加密机制、解析JS源码以获取加密参数,并利用AES加密模块进行数据加密,最终成功发送POST请求获取评论数据。同时,代码中还涉及到对加密函数的分析和重写,以及使用requests库进行网络请求。
摘要由CSDN通过智能技术生成

代码中只用更换data数据,即可爬取别的热评

data数据在检查的network xhr里的预览里找到评论,复制url,其实url都不用改动,在有send的页面标记上,点击提取直到loacal 里的request里面的url出现comment,此时将数据信息复制到data里面运行即可爬取页面,再用re模块解析得到想要的评论

注:部分代码非原创,仅仅是作为个人学习总结

代码(非原创,原创为bilibili up主路飞学城IT)

 #网页不能直接访问,结合上图说明有加密

#需要找到加密函数,通过将数据加密再发送给服务器,这样requests就能获取请求的页面

import requests  
from Crypto.Cipher import AES   

#这里我用的python3.9,我这里3.7环境不支持,3.9下载了pycryptodome 和 Crypto模块
#这里是加密的模块

from base64 import b64encode
import json

url = 'https://music.163.com/weapi/comment/resource/comments/get?csrf_token='

data = {
'cursor': '-1',
'offset': '0',
'orderType': '1',
'pageNo': '1',
'pageSize': '20',
'rid': "R_SO_4_33599439",
'threadId': "R_SO_4_33599439",
}

#data数据获取在最上面已提,这里不再赘述

#因为通过call stack 发现数据的变化是在某个call stack执行后发生的,即在观察相邻的两个call #stack时data的内容发生了变化,即变成了

#encSecKey: "xxxxxxxxxxxxxxx"

#encText: "yyyyyyyyyyyyyy"

#因此可以确定是上面的那个call stack是使函数发生变化的站(js脚本最后加载的信息在最上面)

#于是在这个call stack 里寻找具体使data变化的函数,找到函数后搜索改函数查看函数的源代码

 #以下多行代码里即为函数的源代码

'''
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,
            mode: CryptoJS.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) {  e:"010001"  f:f    g:"0CoJUm6Qyw8W8jud"
        var h = {}
          , i = a(16);
        return h.encText = b(d, g),
        h.encText = b(h.encText, i),
        h.encSecKey = c(i, e, f),
        h
    }
'''

 

f = "00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7"

# f 的获取是通过在js脚本中搜索window.asrsea找到下面的函数,将第三个参数bva4e(.*?)在console运行得到的,前提是先要选中下行函数运行一次,才能在console里运行第三个参数,将在console获取的结果复制给f

g = "0CoJUm6Qyw8W8jud"

e  = "010001"

#g的获取与 f 相似,是用上面函数的第四个参数在console运行后得到的

#b的获取与g相同,是第二个参数在console运行

#window。arssea的第一个函数则说明data的格式为字符串形式,所以后面要用json转换格式

i = "B06pf1H93X5YeOEw"

#通过上面的 多行注释 中的d函数可得到 h.encSecKey = c(i, e, f)  (在d函数内)

#可知encSecKey只与i有关,而e,f都为固定值,因此找到了i,就有了encSecKey

#而在 d 函数源码中有 i ,因此需要将js定位到 , i = a(16);  并执行 ,即可获取 i的值

#上图使将执行条定位到13244行,定位之后点击三角旁边的执行,即可获得 i 的值(下图)

#再继续点击执行按钮 ,直到13247行执行完成,此时就得到了encSecKey的值

#双击蓝色圈中的位置,即可全部复制

 
 

def get_encSecKey():
            
     return
"8896b415b24d3fbaad2e2fde7f55769064647d9aac52b8b73e4c9b2d3178145a14a70d90506feaf3f34995a0e42c8f429fc254bfd809756cfcaa9aa2b289f18cebfec173d67a565c7ef239260fadf72ba057f92dba2bd9afcaae8e66daeda9f130102c8d6f9a9cce87d9bfd31938cb61a4b453dcba30bda29fc1eb7420253dca"

#将上面此时 i 对应的 encSecKey(上图蓝色圈中的)复制 并封装为函数 get_encSecKey()

def get_params(data):
    first = enc_params(data,g)
    second = enc_params(first,i)
    return second

#将要用到的 d 函数重写(get_params(data))  ,根据d原函数中return h.encText = b(d, g),

#可知b的函数用两个,一个为data,还一个为g(恒定值),所以只带一个参数
 

def to_16(data):
    pad = 16 - len(data)%16
    data += chr(pad) * pad
    return  data

#ASE加密所需要的函数,ASE加密的数据必须是16的倍数,不足16位的用 chr(不足的个数)* 不足的个数 补全(即差n个到16的倍数,就用n * chr(n)补上)

#若是16位,则再用16个chr(16)补全

def enc_params(data,key):
    data = to_16(data)
    iv = "0102030405060708"
    aes = AES.new(key = key.encode('utf-8'),IV= iv.encode('utf-8'),mode = AES.MODE_CBC)
    bs = aes.encrypt(data.encode('utf-8'))
    return str(b64encode(bs),'utf-8')

#重写的b函数,首先将data转换格式(用to_16函数) iv是b函数原码中带有的字符串

#由b原函数中带有f = CryptoJS.AES.encrypt,因此重写的函数需要用AES加密

#创建一个加密器ase , ASE.new有三个参数 第一个是编码格式,第二个是加密要用到的字符串iv,第三个是加密的模式,c的原函数mode: CryptoJS.mode.CBC指出模式

要注意前两个参数都是字符串的形式输入,都用到了encode转码

#bs即使用加密器ase加密转码为’utf-8‘字符串形式的数据后而得到的加密数据 即是 被加密的params数据

resp = requests.post(url,data={
    "params":get_params(json.dumps(data)),
    "encSecKey":get_encSecKey()
})

#这里是requests请求url


    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值