zoukankan      html  css  js  c++  java
  • 当爬虫遇到js加密

    当爬虫遇到js加密

      我们在做python爬虫的时候经常会遇到许多的反爬措施,js加密就是其中一种。

      破解js加密的方法也有很多种:

        1.直接驱动浏览器抓取数据,无视js加密。

        2.找到本地加密的js代码,使用python的相关库直接运行js代码。

        3.找到本地加密的js代码,理清加密逻辑,然后用python代码来模仿js代码的流程,生成我们想要的加密的数据。

      这里我们简单介绍一下第三种,也是最难的一种。

    • 目标网站:http://tool.liumingye.cn/music/?type=qq&name=%E4%BD%A0%E5%A5%BD(测试)
    • 在谷歌浏览器输入该网址之后,打开F12开发者工具,访问该链接,很容易在里面找到name为'a8ba90546fd6dc43e933a46c80d9e5df'的请求,这条请求内容就是我们想要的。

    • 观察这条请求的url:http://lab.liumingye.cn/api/ajax/search/text/5L2g5aW9/page/1/type/qq/token/a8ba90546fd6dc43e933a46c80d9e5df,在这里面也很容易发现只有两个变化的参数[`5L2g5aW9`,`a8ba90546fd6dc43e933a46c80d9e5df`](多输入几次不一样的关键词也可以发现规律)

    • 这两个参数肯定都和输入的关键字有关系,后面32位的字符串猜测是md5生成的(md5加密生成的字符串是32位),因为md5加密不可逆,所以网站后台也无法通过该字符串来获取用户输入的关键字。所以我们猜测第一个变化的字符串就是由关键字直接加密变化来的,而且是可逆的。

    • 可逆的加密方式第一个想到的就是利用base64加密,自己试了下,果然这个字符串就是通过base64生成的。
    • 因为md5不可逆,所以必须找到它是如何生成的。复制这个字符串在前面请求中的返回值中查找,结果找不到。这时可以判定该字符串不是由服务器返回,而是本地通过js生成的,我们只用找到加密的js代码就可以了。
    • 正常的访问网站只会加载两个js脚本,一个是空的,另一个名为:`localstorage.js?v=20190301`,查看这个请求的响应,里面有串`whir.res.loadJs("main", "https://lmy.nos-eastchina1.126.net/music/js/main.js?v=20190301", "20190301")`,复制这条代码里面的链接,会自动下载这个js脚本(谷歌浏览器)

    • 下载完成后打开,刚才我们猜测该字符串是通过md5生成的,所以我们直接ctrl+f搜索'md5',搜索完成之后会出现两个匹配的结果,第一个是一个函数的形式,第二个出现在字符串中,很显然我们要的是第一个,包裹这条函数的完整行代码是:'url':_0x940f42[_0x2699('0x43f', '(0%N')](_0x940f42[_0x2699('0x440', '94!y')](_0xd3b949 + _0x940f42['xrghN'], _0x36a191) + _0x2699('0x441', 'hn#I'), md5(_0x36a191 + _0x940f42['tFjdt']))

    • 很显然这段代码做了一定的处理,我们无法直接得知这里面是什么内容。我们先从md5括号里面的找起,复制'_0x36a191'到完整的js代码里面查找,然后会找打一段比较长的代码:

      `_0x36a191 = _0x940f42['BMdWK'](_0x940f42['BMdWK'](_0x940f42['jTMsB'](_0x940f42[_0x2699('0x4c0', '94!y')](_0x2699('0x4c1', 'S]7#') + window[_0x2699('0x4c2', '7l)O')](utf8[_0x2699('0x4c3', 'hn#I')](_0x581614))[_0x2699('0x4c4', 'Kj]n')](///g, '*'), _0x2699('0x4c5', '%L%W')), _0x44fdca), '/type/'), _0x5ebc3e);`,这个看上去还要继续分析,我们暂时不管它。

    • 第二个要找的就是'_0x940f42['tFjdt']',先复制'tFjdt'到js代码里面查找,然后会发现_0x940f42['tFjdt'] = _0x2699('0x437', 'gKGX')。
    • 接着在继续找下去会有点麻烦,我们直接打开刚才访问的链接,打开Console,复制_0x2699('0x437', 'gKGX')到控制台回车,结果给我们返回了一个"tool.liumingye.cn"的字符串。最后我们得知_0x940f42['tFjdt'] == "tool.liumingye.cn",然后再按这种方式查找别的,以此类推。

    • 最后我们会发现之前的

      'url':_0x940f42[_0x2699('0x43f', '(0%N')](_0x940f42[_0x2699('0x440', '94!y')](_0xd3b949 + _0x940f42['xrghN'], _0x36a191) + _0x2699('0x441', 'hn#I'), md5(_0x36a191 + _0x940f42['tFjdt']))

      变成了

      'url': http://lab.liumingye.cn/api/ + ajax/search/ + _0x36a191 + /token/, md5(0x36a191 + tool.liumingye.cn)

      而我们分析的链接为

      `http://lab.liumingye.cn/api/ ajax/search/ text/5L2g5aW9/page/1/type/qq /token/ a8ba90546fd6dc43e933a46c80d9e5df

      两链接一减,很容易的出_0x36a191 = text/5L2g5aW9/page/1/type/qq, md5(0x36a191 + tool.liumingye.cn) = a8ba90546fd6dc43e933a46c80d9e5df

    • 最后我们把_0x36a191 和 'tool.liumingye.cn' 相加,然后把得到的新的字符串通过md5加密,得到的新的字符串就是最后结尾的字符串了!

    最终代码很简单,只要是分析它的加密方式

     1 def get_token(base64str):
     2     """
     3     获取token
     4     :param base64str:
     5     :return: md5的字符串类型
     6     """
     7     md5 = hashlib.md5()
     8     salt = 'tool.liumingye.cn'
     9     code = 'text/%s/page/1/type/qq%s' % (base64str, salt)
    10     md5.update(code.encode())
    11     return md5.hexdigest()
    12 
    13 
    14 def get_base64(key_word):
    15     """
    16     将输入的关键字转化为base64
    17     :param key_word:
    18     :return: base64str
    19     """
    20     key_word = key_word.encode()
    21     base64str = base64.b64encode(key_word)
    22     base64str = base64str.decode()
    23     return base64str
    24 
    25 
    26 def get_content(base64str, token):
    27     url = 'http://lab.liumingye.cn/api/ajax/search/text/%s/page/1/type/qq/token/%s' % (base64str, token)
    28     headers = {'User-Agent': 'Mozilla/5.0'}
    29     response = requests.get(url, headers=headers).json()
    30     return response['data']['list'] if response['code'] == 200 else None
    31 
    32 
    33 
    34 def main(key_word):
    35     base64str = get_base64(key_word)
    36     token = get_token(base64str)
    37     result = get_content(base64str, token)
    38     print(result)
    39 
    40 
    41 if __name__ == '__main__':
    42     keyword = input("请输入想要下载的曲名>>>")
    43     main(keyword)
  • 相关阅读:
    根据修改时间来获取文件
    juery学习总结——例子
    juery实现贪吃蛇的游戏
    juery学习总结(二)——juery操作页面元素
    juery学习总结(一)——juery选择器
    装饰器
    58同城招聘_爬虫解码ncs--#&X
    断点调试_PDB
    Nginx入门
    Windows环境下nginx的安装
  • 原文地址:https://www.cnblogs.com/ivy-blogs/p/10612015.html
Copyright © 2011-2022 走看看