对 js加密数据进行爬取和解密

  • 分析:

    • 爬取的数据是动态加载
    • 并且我们进行了抓包工具的全局搜索,没有查找到结果
      • 意味着:爬取的数据从服务端请求到的是加密的密文数据
    • 页面每10s刷新一次,刷新后发现数据更新,但是浏览器地址栏的url没有变,说明加载出的数据是由ajax请求到的。
      • 动态加载出来的数据是由ajax请求到的,并且请求到的数据为加密数据
    • 定位到ajax数据包,从中可以看到url和动态变化的请求参数和加密的相应数据
    • 将ajax请求到的密文数据捕获
      • 动态的获取动态变化的请求参数
      • 基于抓包工具进行了动态变化请求参数taken的全局搜索,定位到了taken产生的源头,就是如下js代码:
        • var token = md5(String(page) + String(num) + String(timestamp));
    • 对密文数据进行解密
      • 通过分析找到了解密的js函数:decode_str(encode_str),encode_str就是密文数据
    • 查找encode_str的实现:
      • js逆向:将js代码转换成python代码。开发环境只能执行python代码
  • 首先将js代码中的ASCII码进行转换:
  1. function decode_str(scHZjLUh1) {
  2. #Base64.decode(scHZjLUh1)
  3. scHZjLUh1 = Base64["\x64\x65\x63\x6f\x64\x65"](scHZjLUh1);
  4. key = '\x6e\x79\x6c\x6f\x6e\x65\x72';#key = 'b'nyloner'
  5. len = key["\x6c\x65\x6e\x67\x74\x68"];
  6. code = '';
  7. for (i = 0; i < scHZjLUh1["\x6c\x65\x6e\x67\x74\x68"]; i++) {
  8. var coeFYlqUm2 = i % len;
  9. code += window["\x53\x74\x72\x69\x6e\x67"]["\x66\x72\x6f\x6d\x43\x68\x61\x72\x43\x6f\x64\x65"](scHZjLUh1["\x63\x68\x61\x72\x43\x6f\x64\x65\x41\x74"](i) ^ key["\x63\x68\x61\x72\x43\x6f\x64\x65\x41\x74"](coeFYlqUm2))
  10. }
  11. return Base64["\x64\x65\x63\x6f\x64\x65"](code)
  12. }
  1. '\x64\x65\x63\x6f\x64\x65'.encode('utf-8')
  2. b'decode'
  1. function decode_str(scHZjLUh1) {
  2. #Base64.decode(scHZjLUh1)
  3. scHZjLUh1 = Base64.decode(scHZjLUh1);
  4. key = 'nyloner';
  5. len = key.length;
  6. code = '';
  7. for (i = 0; i < scHZjLUh1.length; i++) {
  8. var coeFYlqUm2 = i % len;
  9. code += window.String.fromCharCode(scHZjLUh1.charCodeAt(i) ^ key.charCodeAt(coeFYlqUm2))
  10. }
  11. return Base64.decode(code)
  12. }
  • 代码实现:
  1. import time
  2. import hashlib
  3. import requests
  4. import base64

将js代码装换成python代码:

  1. #js逆向之后的结果
  2. def decode_str(scHZjLUh1):
  3. #解密成字符串
  4. scHZjLUh1 = base64.decodestring(scHZjLUh1.encode())
  5. key = 'nyloner'
  6. lenth = len(key)
  7. code = ''
  8. sch_lenth = len(scHZjLUh1)
  9. for i in range(sch_lenth):
  10. coeFYlqUm2 = i % lenth
  11. #chr(0-255)返回对应编码的字符
  12. #ord(a-z)返回编码数值
  13. code += chr(scHZjLUh1[i] ^ ord(key[coeFYlqUm2]))
  14. code = base64.decodestring(code.encode())
  15. code = code.decode('utf-8')
  16. return code
  1. def getToken():
  2. page = str(1)
  3. num = str(15)
  4. t = str(int(time.time()))
  5. md5 = hashlib.md5()
  6. md5.update((page+num+t).encode('utf-8'))
  7. token = md5.hexdigest()
  8. return token
  1. token = getToken()
  2. url = 'https://nyloner.cn/proxy'
  3. param = {
  4. 'num':'15',
  5. 'page':'1',
  6. 't':str(int(time.time())),
  7. 'token':token
  8. }
  9. headers = {
  10. 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36',
  11. 'Cookie':'sessionid=20ryihg87smnkko2kx6634jbcf4umhfp'
  12. }
  13. # 获取的是一个json串
  14. code = requests.get(url,headers=headers,params=param).json().get('list')
  15. str_code = decode_str(code)
  16. str_code

下面是js代码中的获取数据和调用解密函数的部分代码:

  1. function get_proxy_ip(page, num, click_btn) {
  2. var timestamp = Date.parse(new Date());
  3. timestamp = timestamp / 1000;
  4. var token = md5(String(page) + String(num) + String(timestamp));
  5. $.get('../proxy?page=' + page + '&num=' + num + '&token=' + token + '&t=' + timestamp, function (result) {
  6. if (result.status === 'true') {
  7. var setHtml = "";
  8. $("#ip-list").html(setHtml);
  9. var encode_str = result.list;
  10. var items = str_to_json(decode_str(encode_str));
  11. for (var index = 0; index < items.length; ++index) {
  12. item = items[index];
  13. setHtml += "<tr>\n<td>" + (index + 1) + "</td>\n";
  14. setHtml += "<td>" + item.ip.toString() + "</td>\n";
  15. setHtml += "<td>" + item.port.toString() + "</td>\n";
  16. setHtml += "<td>" + item.time.toString() + "</td>\n</tr>\n";
  17. }
  18. $("#ip-list").html(setHtml);
  19. if (click_btn === 'next') {
  20. document.getElementById("last-page").disabled = false;
  21. if (items.length < 15) {
  22. document.getElementById("next-page").disabled = true;
  23. }
  24. } else {
  25. document.getElementById("next-page").disabled = false;
  26. if (page === 1) {
  27. document.getElementById("last-page").disabled = true;
  28. }
  29. }
  30. }
  31. });
  32. }

对 js加密数据进行爬取和解密的更多相关文章

  1. Node JS爬虫:爬取瀑布流网页高清图

    原文链接:Node JS爬虫:爬取瀑布流网页高清图 静态为主的网页往往用get方法就能获取页面所有内容.动态网页即异步请求数据的网页则需要用浏览器加载完成后再进行抓取.本文介绍了如何连续爬取瀑布流网页 ...

  2. Node.js 动态网页爬取 PhantomJS 使用入门(转)

    Node.js 动态网页爬取 PhantomJS 使用入门 原创NeverSettle101 发布于2017-03-24 09:34:45 阅读数 8309  收藏 展开 版权声明:本文为 winte ...

  3. Node.js 薄荷网爬取

    Node.js:是一个基于前端的服务器,主要的特点:单线程,异步I/O(对这个没有了解,开发起来真的会踩很多坑),事件驱动 前言:本人主要是一个以使用.Net平台下的语言,进行开发的一个菜鸡,之前面试 ...

  4. 淘宝地址爬取及UI展示

    淘宝地址爬取及UI展示 淘宝国家省市区街道获取 参考 foxiswho 的 taobao-area-php 部分代码,改由c#重构. 引用如下: Autofac MediatR Swagger Han ...

  5. Python 爬取 热词并进行分类数据分析-[简单准备] (2020年寒假小目标05)

    日期:2020.01.27 博客期:135 星期一 [本博客的代码如若要使用,请在下方评论区留言,之后再用(就是跟我说一声)] 所有相关跳转: a.[简单准备](本期博客) b.[云图制作+数据导入] ...

  6. js加密数据爬取

    - 中国空气质量在线监测分析平台是一个收录全国各大城市天气数据的网站,包括温度.湿度.PM 2.5.AQI 等数据,链接为:https://www.aqistudy.cn/html/city_deta ...

  7. 爬虫05 /js加密/js逆向、常用抓包工具、移动端数据爬取

    爬虫05 /js加密/js逆向.常用抓包工具.移动端数据爬取 目录 爬虫05 /js加密/js逆向.常用抓包工具.移动端数据爬取 1. js加密.js逆向:案例1 2. js加密.js逆向:案例2 3 ...

  8. Python之手把手教你用JS逆向爬取网易云40万+评论并用stylecloud炫酷词云进行情感分析

    本文借鉴了@平胸小仙女的知乎回复 https://www.zhihu.com/question/36081767 写在前面: 文章有点长,操作有点复杂,需要代码的直接去文末即可.想要学习的需要有点耐心 ...

  9. 利用scrapy-splash爬取JS生成的动态页面

    目前,为了加速页面的加载速度,页面的很多部分都是用JS生成的,而对于用scrapy爬虫来说就是一个很大的问题,因为scrapy没有JS engine,所以爬取的都是静态页面,对于JS生成的动态页面都无 ...

随机推荐

  1. DRF类视图让你的代码DRY起来

    刚开始写views.py模块的代码,一般都是用def定义的函数视图,不过DRF更推荐使用class定义的类视图,这能让我们的代码更符合DRY(Don't Repeat Yourself)设计原则: 使 ...

  2. kafka rebalance解决方案 -incremental cooperative协议和static membership功能

    apache kafka的重平衡(rebalance),一直以来都为人诟病.因为重平衡过程会触发stop-the-world(STW),此时对应topic的资源都会处于不可用的状态.小规模的集群还好, ...

  3. 使用SimpleDateFormat验证日期格式

    Java中日期格式的验证有很多方式,这里介绍用 java.text.SimpleDateFormat 来实现时间验证的一种简单方式.首先我们要知道 SimpleDateFormat 对象有一个方法 v ...

  4. EF5中使用UnitOfWork

    前言 每次提交数据库都会打开一个连接,造成结果是:多个连接无法共用一个数据库级别的事务,也就无法保证数据的原子性.一致性. 解决办法是:在ObjectContext的CRUD操作基础上再包装一层,提供 ...

  5. wuter 使用了腾讯云Ubuntu系统,但是没有root权限怎么办?

    友情链接: 手把手教你搭饥荒专用服务器(一)-服务器准备工作 手把手教你搭饥荒专用服务器(二)-环境配置及基本使用 手把手教你搭饥荒专用服务器(三)-MOD及其他高级设置 手把手教你搭饥荒专用服务器( ...

  6. python初学者-鸡兔同笼简单算法

    鸡兔同笼问题.假设共有鸡.兔30只,脚90只.求鸡.兔各有多少只 使用for循环快速解决鸡兔同笼问题 for ji in range(0,31): if 2*ji+(30-ji)*4==90: pri ...

  7. 记录第一次使用Vivado——以全加器为例子

    从altera转战xilinx,经典的FPGA到ZYNQ系列,第一站就是先熟悉编译软件Vivado.我就直接跳过软件安装部分了,如有疑问,可以在评论区提出来,我看到了就帮你解答. 首先是是打开界面 然 ...

  8. H5-地理定位/本地存储/拖放

    一.地理定位 Geolocation 兼容性:Internet Explorer 9+, Firefox, Chrome, Safari 和 Opera 支持Geolocation(地理定位). 一次 ...

  9. Spring事务管理?

    事务管理方式: 1.编码方案,不建议使用,具有侵入性,在原有的业务代码基础上去添加事物管理代码 2.声明式事务控制,基于AOP对目标进行代理,不具有侵入性,不需要修改原来的业务代码

  10. 5.从零开始创建一个QT窗口按钮

    如何创建一个QT项目 如何创建一个QT项目 1.创建新项目 2.配置选择 3.增加按钮 4.按钮和窗体的大小标签图标设置 5.信号与槽 6.自定义信号与槽 代码 1.创建新项目 点击文件->新建 ...