JS逆向获取网易云音乐评论并保存到mongodb数据库

2023-11-14

JS逆向获取网易云音乐评论

前言:

这段时间,一直在研究JS逆向,今天小试牛刀一下,利用JS逆向技术获取网易云音乐评论。
在这里插入图片描述

一、分析网页

其实网易云音乐评论的api很好找到的,我们通过F12进入到浏览器(chrome)的开发者模式,因为音乐的评论是动态加载的网页,所以我们可以直接定位到network下的XHR选项,如图:

在这里插入图片描述

经过我们一个个的查找分析,定位到get?csrf_token=这个网页,这个里面就是包含评论信息的内容:
在这里插入图片描述

可以看出这个网页数据属于json格式的数据,里面包含了评论的内容,评论者的信息,评论的发布时间等:

在这里插入图片描述

既然知道了,网页的api在哪,那就好办了,直接请求这个地址就可以了,可是没有这么简单:
在这里插入图片描述

在这里插入图片描述

从图中可以看出,该api的methodpost请求,那么就需要传递post请求的data参数,可以看出该data参数是经过加密的数据,我们必须要找到如何加密这些参数的位置,从而找出如何加密的过程。

在这里插入图片描述

我们通过全局搜索params关键字,经过一个个的分析查找,我们找到了加密这些参数的JS网址文件,打开这个JS文件并格式化显示后,继续通过搜索params定位到了加密这些参数的方法的地方:

在这里插入图片描述

我们可以看出加过断点的这段JS代码就是我们加密这些参数的方法,可是这里面各种各样的中英文参杂到底是什么意思啊,经过分析我们知道这个window.asrsea这个方法里面有4个参数,但是需要我们获取到4个参数才行,经过断点分析后,我们能获取到这4个参数的具体信息:

在这里插入图片描述

这个就是这4个参数的具体信息,第一个参数是一个动态的字典,里面包含的歌曲的id,包含的评论翻页的数,包含了每页评论的条目数,包含了当前的时间戳,其余3个参数都是固定的。因为篇幅有限,具体的JS改写就不在这里过多叙述了。大致的思路就是,通过逆向改写这个JS文件,得到这两个加密的参数,然后通过构建好的参数,对这个api发送请求,获取响应数据,最后提取数据并保存到mongodb数据库。

本案例所用到的模块:
# 导入需要的包
import execjs
import requests
import time
import json
from pymongo import MongoClient

二、构建post请求的data参数

    def get_token_params(self):
        """
        构建JS传递的参数的方法
        :return:
        """
        token_param = {
            "rid": f"R_SO_4_{self.song_id}",
            "threadId": f"R_SO_4_{self.song_id}",
            "pageNo": str(self.page),
            "pageSize": "20",
            "cursor": f"{str(self.timestamp)}",
            "offset": "40",
            "orderType": "1",
            "csrf_token": ""}
        return json.dumps(token_param)

    def get_post_data(self):
        """
        逆向JS并获取post请求的data数据的方法
        :return:
        """
        token_param = self.get_token_params()
        with open('./wyy_comment.js', 'r', encoding='utf-8') as jsfile:
            js_code = execjs.compile(jsfile.read())
            result = js_code.call('get_token', f'{token_param}')
        return {
            "params": result.get('encText'),
            "encSecKey": result.get('encSecKey'),
        }

三、发送请求,获取响应数据

 def params_url(self, url):
        """
        发送请求,获取响应数据的方法
        :param url:
        :return:
        """
        data = self.get_post_data()
        response = requests.post(url, headers=self.headers, data=data)
        if response.status_code == 200:
        	return response.json()
        else:
           print('网页请求不成功')
四、提取评论的数据信息并保存到mongodb数据库
    def get_comment_data(self, json_str):
        """
        提取评论数据的方法
        :param json_str:
        :return:
        """
        for json_data in json_str.get('data').get('comments'):
            time_temp = time.localtime(json_data.get('time') // 1000)
            comment_time = time.strftime("%Y-%m-%d %H:%M:%S", time_temp)
            yield {
                # 提取评论者名字
                'comment_nickname': json_data.get('user').get('nickname'),
                # 提取评论者id
                'comment_userId': json_data.get('user').get('userId'),
                # 提取评论内容
                'comment_content': json_data.get('content'),
                # 提取评论发布时间
                'comment_time': comment_time,
                # 提取评论id
                'comment_commentId': json_data.get('commentId'),
            }

    def save_mongo(self, comment_data):
        """
        保存到mongodb数据库的方法
        :param comment_data:
        :return:
        """
        self.wyy_comment.insert_one(comment_data)

    def run(self):
        """
        实现主要逻辑思路的方法
        :return:
        """
        # 1.发送请求,获取响应数据
        json_str = self.params_url(self.API_COMMENT_URL)
        # 2.提取音乐评论数据
        comment_list = self.get_comment_data(json_str)
        for comment_data in comment_list:
            # 3.保存数据到mongodb数据库
            self.save_mongo(comment_data)
            print('保存mongo数据库成功')

五、具体实现思路

    def run(self):
        """
        实现主要逻辑思路的方法
        :return:
        """
        # 1.发送请求,获取响应数据
        json_str = self.params_url(self.API_COMMENT_URL)
        # 2.提取音乐评论数据
        comment_list = self.get_comment_data(json_str)
        for comment_data in comment_list:
            # 3.保存数据到mongodb数据库
            self.save_mongo(comment_data)
            print('保存mongo数据库成功')
效果展示:

在这里插入图片描述

由于JS代码太长了,在这里只展示JS改写后的部分代码:

在这里插入图片描述

六、完整代码

# 导入需要的包
import execjs
import requests
import time
import json
from pymongo import MongoClient


class WyyCommentSpider:
    """爬取网易云音乐评论"""
    def __init__(self,song_id,page):
        self.API_COMMENT_URL = 'https://music.163.com/weapi/comment/resource/comments/get?csrf_token='
        self.headers = {
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 FS'
        }
        self.timestamp = int(time.time()) * 1000
        client = MongoClient(host='localhost', port=27017)
        self.wyy_comment = client['test']['comment']
        self.song_id = song_id
        self.page = page


    def get_token_params(self):
        """
        构建JS传递的参数的方法
        :return:
        """
        token_param = {
            "rid": f"R_SO_4_{self.song_id}",
            "threadId": f"R_SO_4_{self.song_id}",
            "pageNo": str(self.page),
            "pageSize": "20",
            "cursor": f"{str(self.timestamp)}",
            "offset": "40",
            "orderType": "1",
            "csrf_token": ""}
        return json.dumps(token_param)

    def get_post_data(self):
        """
        逆向JS并获取post请求的data数据的方法
        :return:
        """
        token_param = self.get_token_params()
        with open('./wyy_comment.js', 'r', encoding='utf-8') as jsfile:
            js_code = execjs.compile(jsfile.read())
            result = js_code.call('get_token', f'{token_param}')
        return {
            "params": result.get('encText'),
            "encSecKey": result.get('encSecKey'),
        }

    def params_url(self, url):
        """
        发送请求,获取响应数据的方法
        :param url:
        :return:
        """
        data = self.get_post_data()
        response = requests.post(url, headers=self.headers, data=data)
        assert response.status_code == 200
        return response.json()

    def get_comment_data(self, json_str):
        """
        提取评论数据的方法
        :param json_str:
        :return:
        """
        for json_data in json_str.get('data').get('comments'):
            time_temp = time.localtime(json_data.get('time') // 1000)
            comment_time = time.strftime("%Y-%m-%d %H:%M:%S", time_temp)
            yield {
                # 提取评论者名字
                'comment_nickname': json_data.get('user').get('nickname'),
                # 提取评论者id
                'comment_userId': json_data.get('user').get('userId'),
                # 提取评论内容
                'comment_content': json_data.get('content'),
                # 提取评论发布时间
                'comment_time': comment_time,
                # 提取评论id
                'comment_commentId': json_data.get('commentId'),
            }

    def save_mongo(self, comment_data):
        """
        保存到mongodb数据库的方法
        :param comment_data:
        :return:
        """
        self.wyy_comment.insert_one(comment_data)

    def run(self):
        """
        实现主要逻辑思路的方法
        :return:
        """
        # 1.发送请求,获取响应数据
        json_str = self.params_url(self.API_COMMENT_URL)
        # 2.提取音乐评论数据
        comment_list = self.get_comment_data(json_str)
        for comment_data in comment_list:
            # 3.保存数据到mongodb数据库
            self.save_mongo(comment_data)
            print('保存mongo数据库成功')


if __name__ == '__main__':
    song_id = input('请输入你需要搜索的歌曲评论的ID:')
    for page in range(1,10):
        wyy_comment_spider = WyyCommentSpider(song_id,page)
        wyy_comment_spider.run()
写在后面的话:

本案例需要了解一些JS逆向方面的知识,了解一点JavaScript基本用法,函数的调用等。另外网易云音乐爬取歌曲,也是像本案例一样,需要逆向出这两个参数,就可以提取出歌曲的真实url地址了,只不过提取歌曲比较麻烦些,但是总的关键都是需要逆向破解加密的参数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JS逆向获取网易云音乐评论并保存到mongodb数据库 的相关文章

随机推荐

  • 【Unity】新InputSystem中点按UI组件模拟键盘输入

    项目中用空格作为对话的交互键 想要实现对话时点按UI中的panel和空格有一样的效果 文档中创建event并传入的方法 原文地址 Input events Input System 1 3 0 第二个方法第二个参数搞不懂应该传入什么 第一个
  • 为你的VMware 15.5 虚拟机MacOS系统手动安装VMware Tools

    本博客同步发布在 为你的VMware 15 5 虚拟机MacOS系统手动安装VMware Tools VMware Tools 是VMware软件提供的一个辅助工具 可以提升虚拟机的使用体验 默认伴随虚拟机自动安装 但有时候自动安装会出错
  • 像数字化原生代那样思考——企业数字化转型的挑战与应对

    点击上方 中国云报 可关注 似乎是一眨眼间 90后 甚至 00后 已经成长起来 渐渐成了消费的主力军 他们使用的是各类移动智能设备 形形色色的社交工具 对云计算 大数据天生就具有亲近感 IDC有一个词来形容这一代消费者 数字化原生代 面对数
  • grafana创建dashboard

    前提 安装grafana 创建dashboard 点击侧边栏菜单Dashboards下的New dashboard 点击Add a new panel 进入到 New dashboard Edit 面板视图 到Query 标签页 配置你的Q
  • Android 隐藏虚拟按键,并且全屏

    隐藏虚拟按键 并且全屏 protected void hideBottomUIMenu 隐藏虚拟按键 并且全屏 if Build VERSION SDK INT gt 11 Build VERSION SDK INT lt 19 lower
  • 并发下sftp连接报错——com.jcraft.jsch.JSchException: connection is closed by foreign host

    当对单接口极限测试时 随着并发量上升 接口稳定性出现不稳定的情况 排查后台日志 发现报错在该接口调用sftp上传时出现问题 确切的是在初始化连接时失败 原因 系统SSH终端连接数配置过小 查看虚拟机该参数 该参数在 etc ssh sshd
  • 【操作系统】虚拟存储器概述

    存储管理分类 实存管理 分区 Partitioning 连续分配方式 包括固定分区 可变分区 分页 Paging 分段 Segmentation 段页式 Segmentation with paging 虚存管理 请求分页 Demand p
  • java 虚拟机类装载的原理、实现、以及应用

    一 引言 Java虚拟机 JVM 的类装载就是指 将包含在类文件中的字节码装载到JVM中 并使其成为JVM一部分的过程 JVM的类动态装载技术能够在运行时刻动态地加载或者替换系统的某些功能模块 而不影响系统其他功能模块的正常运行 本文将分析
  • python linux运行环境,Linux平台Python运行环境配置

    1 软件包管理工具 pip xiaokang localhost sudo yum install python2 pip 查看pip版本 xiaokang localhost pip V 大v pip 8 1 2 from usr lib
  • mysql8和5.7区别_MySQL8.0和MySQL 5的区别

    虽然MySQL8 0 x都出来了 自己一直使用 5 7的版本 对于新的版本今天抽了些时间来了解一下新的特性 而对于新的版本的了解往往都是从版本区别开始的 今天便算是作一个笔记吧 Oracle发布新版本的MySQL时 直接从5 7 x 跳到了
  • Redhat8.2 linux 忘记root密码破解方法 最详细!!!!!

    root密码破解方法 第一步 重启虚拟机 在开机标题界面 选择系统 按E进入 第二步 进入后在含LINUX开头结尾处加上 rd break 然后按CTRL X进入系统 第三步重新挂载根目录并给予读写权限 否则无法重置密码 第四步切换根目录位
  • TCP通信详解

    一 TCP简介 1 TCP介绍 a gt TCP协议 TCP协议 传输控制协议 英语 Transmission Control Protocol 缩写为 TCP 是一种面向连接的 可靠的 基于字节流的通信协议 1 面向连接 先连接 再通信
  • 疯壳-鸿蒙OS-HDF驱动框架

    一 简介 HDF HarmonyOS Driver Foundation 驱动框架 为驱动开发者提供驱动框架能力 包括驱动加载 驱动服务管理和驱动消息机制 旨在构建统一的驱动架构平台 为驱动开发者提供更精准 更高效的开发环境 力求做到一次开
  • 网络安全毕业设计题目大全

    文章目录 0 简介 1 如何选题 2 最新网安毕设选题 0 简介 毕业季马上就要开始了 不少同学询问学长管理选题开题类的问题 今天跟大家分享信息安全毕设选题 最新的信息安全 网络安全 专业毕设选题 难度适中 适合作为毕业设计 大家参考 学长
  • RuntimeError:shape ‘[4, 3, 85, 80, 80]‘ is invalid for input of size 537600

    在对yolov5进行剪枝训练时出现以下类型的错误 错误原因 1 使用自己 的数据集时 数据集与源代码的数据集的类别数不同 没有修改成对应的类别数 解决办法 修改cfg文件 把classes和filters进行修改 filters class
  • 启用电脑对远程服务器的访问,未启用对服务器的远程访问 win10家庭版

    未启用对服务器的远程访问 win10家庭版 卡饭网 本站整理 2019 07 09 这个问题比较常见小编整理的解决方法如下 方法一 用QQ远程协助对方电脑 需要QQ告诉对方右键单击计算机 这台电脑 点管理 打开计算机管理界面 选择本地用户和
  • git 工具使用--分支管理

    git 工具使用 分支管理 文章目录 git 工具使用 分支管理 理解分支 创建分支 切换分支 合并分支 删除分支 合并冲突 分支管理策略 分支策略 bug分支 删除临时分支 总结 理解分支 分支管理是Git的杀手级功能之一 分支 就是科幻
  • Ajax的核心技术XMLHttpRequest方法

    整个Ajax技术紧紧围绕在XMLHttpRequest对象的周围 Ajax整个技术的过程如下 XMLHttpRequest发送请求 在与服务器交互中 其readyState状态可以监听到服务器 的响应状态 当服务器的响应完成的时候 XMLH
  • 【UiBot】RPA流程机器人有几种类型?

    RPA Robotic Process Automation 机器人流程自动化 是指通过软件自动化方式 使各个行业中本来是人工操作计算机完成的业务 实现工作流程的自动化 RPA机器人的交互方式大致可分为两大主要类型 人机交互型和无人值守型
  • JS逆向获取网易云音乐评论并保存到mongodb数据库

    JS逆向获取网易云音乐评论 前言 这段时间 一直在研究JS逆向 今天小试牛刀一下 利用JS逆向技术获取网易云音乐评论 一 分析网页 其实网易云音乐评论的api很好找到的 我们通过F12进入到浏览器 chrome 的开发者模式 因为音乐的评论