爬虫学习4-寒假系列(3)

网抑云热评爬取

流程:

  1. 找到未加密的参数
  2. 把参数加密(按照网易的规则)-params和encSecKey
  3. 请求到网易云,拿到评论信息

难点1:需要从脚本执行过程找到未加密的参数;
难点2:需要通过设置断点的方式查看参数的变化,也是上一个难点需要用到的;
难点3:需要弄懂加密原理(这一点反倒是密码学的范畴)
难点4:将加密过程简化并实现出来(这一点是精髓)
在这里插入图片描述
这两个参数是加密过了的,我们就是任务就是要模拟网易云的加密过程,加密参数传递给浏览器。

1)新工具,call stack调用的栈,即当我发送请求到左侧文件时,有哪些js脚本执行的过程,排列为从下至上
2)设置断点,查看参数和变量值
3)多学会通过栈来模拟网站渲染流程
4)学会简化网站加密过程
判断参数是否可以固定,如果可以固定,则可以从网页中获取相关参数,尽量减少随机参数。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
现在需要做的是弄明白程序是怎么加密的。
离谱
太复杂了
别看代码少,但是复杂啊,涉及到的东西。代码是精髓,通过固定参数的方法,将最终需要的参数加密出来;但找这个加密过程以及实现加密过程很强。这一个项目给我干懵了,休息会儿。
光看代码和笔记估计大概率是搞不出来的,一脸懵,当然要排除掉大神们
#pycrypto模块是提供加密算法
#base64模块是用来转变为字节,让utf-8能识别吧
#json模块是转变为json中的字符串
下面是跟着流程从网站上获取的加密规则,而我们的任务就是弄懂加密原理,然后我们将加密过程还原出来,教程的简化太强了。

# 加密过程(截取的网站上的加密算法)
    function a(a=16) { # 返回的c是随机的16位字符串
        var d, e, b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", c = "";
        for (d = 0; a > d; d += 1)# 循环16次
            e = Math.random() * b.length,# 随机数
            e = Math.floor(e),# 取整
            c += b.charAt(e);# 取字符串的xxx位置
        return c
    }
    function b(a, b) { # a是要加密的内容,
        var c = CryptoJS.enc.Utf8.parse(b) # c是b,因此b就是密钥
          , d = CryptoJS.enc.Utf8.parse("0102030405060708")
          , e = CryptoJS.enc.Utf8.parse(a) # e是数据
          , f = CryptoJS.AES.encrypt(e, c, { # 差一个密钥,c是加密的密钥
            iv: d,  # 偏移量
            mode: CryptoJS.mode.CBC # 加密模式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) {  d:数据data,  e:010001,  f:很长的定值,  g:0CoJUm6Qyw8W8jud
        var h = {} # 空对象
          , i = a(16); # i是16位的随机值
        return h.encText = b(d, g), # g是密钥
        h.encText = b(h.encText, i), # 返回的就是params,i也是密钥
        h.encSecKey = c(i, e, f), # 得到的就是encSecKey,因此两个参数都得到了
        # 把i固定住,那么产生的参数也是个定值,因为i e f只有i是随机数,且c()不产生随机数
        h
        # 这四句是return h,需要看b()和c()
    }

代码:

# 网易云热评爬取
# 步骤
# 1.找到未加密的参数
# 2.把参数加密(按照网易的规则)-params和encSecKey
# 3.请求到网易云,拿到评论信息

# 需要按照pycrypto模块
from Crypto.Cipher import AES
from base64 import b64encode
import requests
import json

# 热评对应的url
url = 'https://music.163.com/weapi/comment/resource/comments/get?csrf_token='
# 请求方式POST

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

# 服务于网页中d()
d = '数据data'
e = '010001'
g = '0CoJUm6Qyw8W8jud'
f = "00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7"

# 是从网站中获取的16个随机值
i = 'KsdKp5dNso9IBwLA'


def get_encSecKey():
    return "91d2e4d1e0f89488235866035cf6e9b601296ee3e71c98720efb82418bcd1b39e7264af215403c9d472ef13310fa81069a8650e19791689c42187196f3b5f1f81b552252caaf9a2659d8b864585f2994895a15d0010dc0b021b51eed2bda25d8f9ebb67f9ae0af6a903328414d81e3a27fcf6455913e3d632ae66c66e8918d90"


# 加密肯定不能用字典,通过json变为字符串
def get_params(data):  # 默认此处的data是字符串
    first = enc_params(data, g)
    second = enc_params(first, i)
    return second  # 返回的就是params


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


def enc_params(data, key):
    iv = "0102030405060708"
    data = to_16(data)
    aes = AES.new(key=key.encode("utf-8"), IV=iv.encode("utf-8"), mode=AES.MODE_CBC)  # 创建加密器
    bs = aes.encrypt(data.encode("utf-8"))  # 加密
    # 加密的要求:加密的内容的长度必须是16的倍数,这是加密规则。
    # 加密完的东西不能直接被utf-8识别
    return str(b64encode(bs), "utf-8")  # 转换为字符串


# 处理加密过程
"""
    function a(a=16) { # 返回的c是随机的16位字符串
        var d, e, b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", c = "";
        for (d = 0; a > d; d += 1)# 循环16次
            e = Math.random() * b.length,# 随机数
            e = Math.floor(e),# 取整
            c += b.charAt(e);# 取字符串的xxx位置
        return c
    }
    function b(a, b) { # a是要加密的内容,
        var c = CryptoJS.enc.Utf8.parse(b) # c是b,因此b就是密钥
          , d = CryptoJS.enc.Utf8.parse("0102030405060708")
          , e = CryptoJS.enc.Utf8.parse(a) # e是数据
          , f = CryptoJS.AES.encrypt(e, c, { # 差一个密钥,c是加密的密钥
            iv: d,  # 偏移量
            mode: CryptoJS.mode.CBC # 加密模式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) {  d:数据data,  e:010001,  f:很长的定值,  g:0CoJUm6Qyw8W8jud
        var h = {} # 空对象
          , i = a(16); # i是16位的随机值
        return h.encText = b(d, g), # g是密钥
        h.encText = b(h.encText, i), # 返回的就是params,i也是密钥
        h.encSecKey = c(i, e, f), # 得到的就是encSecKey,因此两个参数都得到了
        # 把i固定住,那么产生的参数也是个定值,因为i e f只有i是随机数,且c()不产生随机数
        h
        # 这四句是return h,需要看b()c()
    }
"""

# json.dumps(data)将data转换为字符串
if __name__ == '__main__':
    resp = requests.post(url, data={
        "params": get_params(json.dumps(data)),
        "encSecKey": get_encSecKey()
    })
    print(resp.text)

我瞄过还有后续的操作是将爬取的信息进行数据清洗,然后整理出关键热词,形成热词海报。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值