JS逆向-某易云音乐下载器

文章目录

  • 介绍
  • 下载链接
  • Robots文件
  • 搜索功能
  • JS逆向
      • **函数a:生成随机字符串**
      • **函数b:AES-CBC加密**
      • **函数c:RSA公钥加密**
  • 歌曲下载
  • 总结

介绍

在某易云音乐中,很多歌曲听是免费的,但下载需要VIP,此程序旨在“可听”则可下,只要能够听的歌,都可以下载下来。

而此篇博客则着重讲此代码是如何编写的,如果只想要下载工具,请自行查看下载链接。

注意,此程序仅做学习参考,任何违法行为与作者无关。

下载链接

GitHub:https://github.com/13337356453/163Music
CSDN:https://download.csdn.net/download/realmels/90855703

Robots文件

养成好习惯,爬虫之前,先看robots文件。
在这里插入图片描述
禁止爬取

/prime/m/gift-receive

文件,刚好,我们这次不爬取此文件。

搜索功能

在某易云音乐中提供了搜索功能,可以通过关键词搜索歌曲。
在这里插入图片描述
而我们的程序需要通过用户关键词来搜索内容,因此需要首先从搜索功能开始爬取。

在这里通过歌曲abc为例,进行搜索功能的分析与实现。

在搜索栏输入关键字abc,按下回车键得到搜索结果。
在这里插入图片描述
按下F12进入开发者工具,选中Network,点击XHR查看Ajax的请求包

刷新界面,出现了很多请求包
在这里插入图片描述
逐个查看请求包的Response,寻找搜索歌曲的请求包。

在路径为

/weapi/cloudsearch/get/web

的请求包中,我们可以看到歌曲的搜索信息。

在这里插入图片描述
可以确定这个就是搜索歌曲的请求包。

接下来分析请求参数。

在这里插入图片描述
这是一个POST请求,请求的URL为:https://music.163.com/weapi/cloudsearch/get/web
,POST的参数如下:

params=NM406wjNCdicjbT3ZSuA7X6ICkCBzfN6rA1KAeZR4Pmpv6VhTT8jKqR/ZRpGitFCp77TipjrdwPahGWiMjGf2cLrREp5Gadgeseo9l9+IMfrwG/JmgDfW9pLZaRIagi+MSESFlTJnlH3vJI7YbqwWPjgfbyzBX0sgw4l3IXxfuamFggnztM3DlEhB1uCBUPqEpDFlsMW8pPdEPtaJS47Y2DMXBY/SJVOa8Y3nD/rjP2lhw5sXaZ3qs5LEwmYKiriEAaZ6fRmKJb4Vn6Ay6ELCBWL74DqjF4BPh8GsEPicXdah/nR0BPoM+suZbKCICMK
encSecKey=8b987300e7f1a5e657c7a69d3c9ff9a4d9ab1c3dc1b2328df473600103b1fe18aa4898008ac9d03074c2cb560543ac22740c4c0c1f7d2c14535f938344a999224733d97e75ffdc26dc2a7ac9afff302f127b29ee762ce02061b9ce89ad2b9006938ed0e62667bfbac656b12adbe951ccff0d02dacd27fb94de7473fa933043ec

别的都容易理解,这两个参数是什么呢?

我们从JS文件中找答案。

JS逆向

在这里先科普基本知识。一个网站,分为前端和后端,前端负责展现好看的页面,后端负责处理繁杂的数据。用户通过前端界面,将数据发送到后端,后端代码处理数据,将相应的结果发送到前端,呈现在用户眼前。这个过程通过request/response,实现。因此,前端所有奇形怪状的参数,都可以在前端代码中找到蛛丝马迹。毕竟,后端代码是不可见的,而前端代码是公开的。

首先需要明白paramsencSecKey这两个参数是如何产生的,这里我们复制encSecKey,在开发者工具中选中Sources,按下Ctrl+Shift+F进行全局搜索。
在这里插入图片描述
在这里我们逐个进行分析,首先打开这个core开头的JS文件,顾名思义,core就是核心,因此最可能有我们想要的数据。

打开文件后按下Ctrl+F进行文件内搜索,搜索encSecKey,查询到三个结果。
在这里插入图片描述
我们分别进行分析。

在第二次出现的地方,我们需要的两个参数:paramsencsecKey同时出现
在这里插入图片描述
怀疑这里有参数的生成逻辑,打一个断点。
在这里插入图片描述
刷新页面,程序运行到断点处停止。
在这里插入图片描述
可以看到,paramsencsecKey这两个参数分别是bYE4I这个对象的两个属性。而bYE4I这个对象是由window.asrsea这个函数生成的。

我们把光标放到window.asrsea这个函数上,查看这个函数的真实面目。
在这里插入图片描述
跳转到函数d
在这里插入图片描述
我们可以看到,函数d中调用了函数a,b,c。正好这三个参数都在d函数的附近,我们一起复制过来查看。

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) {var h = {}, i = a(16);return h.encText = b(d, g),h.encText = b(h.encText, i),h.encSecKey = c(i, e, f),h}

我们在d函数中打上断点,分析d函数的参数
在这里插入图片描述
一直点击上方的下一步,同时眼睛观察着右边的实时参数值。
在这里插入图片描述
在这里插入图片描述
多走几步,我们会发现函数d接受的四个参数中,efg都是固定值,值如下:

e=010001
f=00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7
g=0CoJUm6Qyw8W8jud

参数d的值却一直在变化。

我们一直点下一步的按钮,同时盯着参数,点着点着,会发现右侧的d参数发生变化,大多数时候都是csrf_token的值,我们不用管,但偶尔会出现别的内容,而大概点了几十次后,参数会变成:

d="{\"hlpretag\":\"<span class=\\\"s-fc7\\\">\",\"hlposttag\":\"</span>\",\"s\":\"abc\",\"type\":\"1\",\"offset\":\"0\",\"total\":\"true\",\"limit\":\"30\",\"csrf_token\":\"\"}"

在其中,出现了我们的关键词abc,以及出现歌曲的数量30

确定d函数就是生成参数的逻辑。

接下来仔细分析d函数

 function d(d, e, f, g) {var h = {}, i = a(16);return h.encText = b(d, g),h.encText = b(h.encText, i),h.encSecKey = c(i, e, f),h}

首先定义了一个空对象h,然后通过a函数生成内容,赋值给i,接下来通过b函数生成第一个encText,赋给h的属性,接受参数dg,再用b函数二次处理encText,参数为第一次处理的encTexti,这就是提交时所需的params;同时用c函数生成encsecKey,接受参数ief

接下来我们逐个分析abc函数

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)}

人与动物的区别就是人会使用工具,我们直接问deepseek

在这里插入图片描述
在这里插入图片描述
这是deepseek的回答。


函数a:生成随机字符串

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
}
  • 功能:生成指定长度的随机字符串,字符集包括大小写字母和数字。
  • 参数a 控制字符串长度。
  • 实现细节
    • 循环 a 次,每次从字符池 b 中随机选取一个字符。
    • 使用 Math.random() 生成随机索引,可能不够安全(非密码学安全随机数)。
  • 安全问题
    • Math.random() 在浏览器中可能被预测,建议改用 crypto.getRandomValues()
  • 用途:生成临时密钥、Nonce 或盐值。

函数b:AES-CBC加密

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()
}
  • 功能:使用 AES-CBC 模式加密数据,密钥由参数提供。
  • 参数
    • a:明文数据(UTF-8 字符串)。
    • b:加密密钥(UTF-8 字符串)。
  • 实现细节
    • 固定初始化向量(IV)0102030405060708
    • 使用 CryptoJS 库进行加密,返回 Base64 编码的密文。
  • 安全问题
    • 固定IV:CBC 模式要求每次加密使用随机 IV,否则可能导致明文模式泄露。
    • 密钥建议使用二进制格式(如 PBKDF2 派生),而非直接字符串。
  • 用途:加密传输敏感数据。

函数c:RSA公钥加密

function c(a, b, c) {var d, e;return setMaxDigits(131),d = new RSAKeyPair(b,"",c),e = encryptedString(d, a)
}
  • 功能:使用 RSA 公钥加密数据。
  • 参数
    • a:明文数据(字符串或数值)。
    • b:公钥指数(通常为 "10001" 十六进制)。
    • c:RSA 模数(n)。
  • 实现细节
    • setMaxDigits(131) 设置大整数位数(支持最大 131 位,对应 1024 位 RSA)。
    • RSAKeyPair 仅使用公钥指数和模数,私钥留空,表明这是公钥加密。
    • encryptedString 可能是自定义函数,实现 RSA 加密逻辑。
  • 安全问题
    • 需确认是否使用正确填充(如 PKCS#1 v1.5 或 OAEP),默认可能不安全。
  • 用途:加密对称密钥(如 AES 密钥)以便安全传输。

知道了函数的用途,我们开始编写Python代码。

写一个工具类,分别实现函数abcd的功能,名字为JS,定义四个静态方法:

import base64
import random
from binascii import hexlifyfrom Crypto.Cipher import AES
from Crypto.Util.Padding import padclass JS:@staticmethoddef d(d,e="010001",f="00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7",g="0CoJUm6Qyw8W8jud"):'''生成数据'''i=JS.a(16)h_encText=JS.b(d,g)encText=JS.b(h_encText,i)encSecKey=JS.c(i,e,f)return encText,encSecKey@staticmethoddef a(a):'''生成16位随机字符'''b="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"c=""for i in range(a):e = random.randint(0, len(b) - 1)c+=b[e]return c@staticmethoddef b(a,b):'''AES加密'''key = b.encode('utf-8')iv = "0102030405060708".encode('utf-8')data = a.encode('utf-8')cipher = AES.new(key, AES.MODE_CBC, iv)encrypted = cipher.encrypt(pad(data, AES.block_size))return base64.b64encode(encrypted).decode('utf-8')@staticmethoddef c(a,b,c):'''RSA加密'''a = a[::-1]result = pow(int(hexlify(a.encode()), 16), int(b, 16), int(c, 16))return format(result, 'x').zfill(131)

至于这几个函数是如何改写的。。其实很简单。
在这里插入图片描述
接下来的步骤就很简单了,编写搜索歌曲功能代码:

import requests
from urllib.parse import quote
from json import loadsfrom JS import JSrequests.packages.urllib3.disable_warnings()
class Searcher:url="https://music.163.com/weapi/cloudsearch/get/web?csrf_token="headers={'Host': 'music.163.com','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36','Referer': 'https://music.163.com/search/','Content-Type': 'application/x-www-form-urlencoded',}jsonStr="{\"hlpretag\":\"<span class=\\\"s-fc7\\\">\",\"hlposttag\":\"</span>\",\"s\":\"%s\",\"type\":\"1\",\"offset\":\"0\",\"total\":\"true\",\"limit\":\"%d\",\"csrf_token\":\"\"}"def __init__(self,keyword,proxies={},number=1,cookie=""):self.keyword=keywordself.proxies=proxiesself.number=numberself.headers['Cookie']=cookiedef getData(self):s=self.jsonStr%(self.keyword,self.number)params,encSecKey=JS.d(s)data=f"""params={quote(params)}&encSecKey={quote(encSecKey)}"""try:r=requests.post(self.url,headers=self.headers,data=data,verify=False,timeout=10,proxies=self.proxies)if r.status_code==200:result=loads(r.content.decode())return result['result']['songs']return Noneexcept Exception as e:print(f'[!] {e}')return None

注意注意,这里有个非常坑的点,就是在传输data中,数据还要进行URL加密,否则就会报400,参数错误。这个点害了我一晚上。

我们成功实现了通过关键字搜索功能,获取到歌曲的idname,这两个参数至关重要

歌曲下载

选中一首歌,我们打开详细页。
在这里插入图片描述
打开开发者工具抓包,同时点击播放按钮
在这里插入图片描述
抓取到数据包后,我们逐个分析。
在这里插入图片描述
锁定到

/weapi/song/enhance/player/url/v1

这个请求包,在请求包中,我们可以看到歌曲的下载链接。
在这里插入图片描述
我们把这个链接复制到浏览器打开,成功播放了歌曲,确定就是下载链接。

在这里插入图片描述
接下来我们分析这个请求包的参数。
在这里插入图片描述
熟悉的paramsencsecKey,我们之前已经分析过了

使用同样方法打好断点,再次点击播放按钮,查看传入的参数。

在这里插入图片描述
这里出现了歌曲id,原始的参数为:

d="{\"ids\":\"[33004804]\",\"level\":\"exhigh\",\"encodeType\":\"aac\",\"csrf_token\":\"\"}"

于是我们可以编写相关Python代码:

from json import loads
from urllib.parse import quoteimport requestsfrom JS import JSrequests.packages.urllib3.disable_warnings()
class Musicer:url='https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token='headers={'Host': 'music.163.com','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36','Referer': 'https://music.163.com/search/','Content-Type': 'application/x-www-form-urlencoded',}jsonStr='{"ids":"[%s]","level":"exhigh","encodeType":"aac","csrf_token":""}'def __init__(self,musicid,cookie,name,proxies={}):self.musicid=str(musicid)self.headers['Cookie']=cookieself.proxies=proxiesself.name=namedef getDownloadUrl(self):s=self.jsonStr%self.musicidparams,encSecKey=JS.d(s)data=f"""params={quote(params)}&encSecKey={quote(encSecKey)}"""try:r=requests.post(self.url,headers=self.headers,data=data,verify=False,timeout=10,proxies=self.proxies)if r.status_code==200:return loads(r.content.decode())['data'][0]['url']return Noneexcept Exception as e:print(e)return Nonedef download(self):url=self.getDownloadUrl()try:r=requests.get(url,proxies=self.proxies,verify=False,timeout=10)if r.status_code==200:with open(f'{self.name}.mp3','wb') as f:f.write(r.content)print(f"[+] {self.name}.mp3 已保存")except Exception as e:print(f'[!] {e}')

至此,本项目全部完成。

总结

本博客仅做学习参考,任何违法犯罪行为与本文作者无关。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/bicheng/81600.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

黑马k8s(十)

1.Pod生命周期-钩子函数 2.Pod生命周期-容器探测 因为没有hello.txt文件 查看详情&#xff1a; 修改为查看命令&#xff1a; 查看一下详情&#xff1a; 因为只有一个80端口&#xff0c;没有8080&#xff0c;所以会重启 查看详情&#xff1a; 修改成80&#xff1a; 因为没有…

每日算法刷题Day9 5.17:leetcode定长滑动窗口3道题,用时1h

9. 1652.拆炸弹(简单&#xff0c;学习) 1652. 拆炸弹 - 力扣&#xff08;LeetCode&#xff09; 思想 为了获得正确的密码&#xff0c;你需要替换掉每一个数字。所有数字会 同时 被替换。 如果 k > 0 &#xff0c;将第 i 个数字用 接下来 k 个数字之和替换。如果 k < 0…

Java IO及Netty框架学习小结

Netty netty官网: Netty 什么是Netty&#xff1f; Netty 是 一个异步事件驱动的网络应用程序框架&#xff0c;用于快速开发可维护的高性能协议服务器和客户端。Netty 是一个 NIO 客户端服务器框架&#xff0c;可以快速轻松地开发网络应用程序&#xff08;例如协议服务器和客…

计算机网络笔记(二十七)——4.9多协议标签交换MPLS

4.9.1MPLS的工作原理 一、MPLS基本工作原理 MPLS&#xff08;Multiprotocol Label Switching&#xff09;是一种介于数据链路层和网络层之间的转发技术&#xff0c;通过固定长度的标签进行高速数据转发。其核心特点是通过预建立的标签交换路径&#xff08;Label Switching Pa…

AI 赋能 Copula 建模:大语言模型驱动的相关性分析革新

技术点目录 R及Python语言及相关性研究初步二元Copula理论与实践&#xff08;一&#xff09;二元Copula理论与实践&#xff08;二&#xff09;【R语言为主】Copula函数的统计检验与选择【R语言为主】高维数据与Vine Copula 【R语言】正则Vine Copula&#xff08;一&#xff09;…

【洛谷P3386】二分图最大匹配之Kuhn算法/匈牙利算法:直观理解

题目&#xff1a;洛谷P3386 【模板】二分图最大匹配 &#x1f955; 匈牙利算法本来是针对带权图最大匹配的&#xff0c;这里由于题目只是求最大匹配的边数&#xff0c;所以我们也只考虑无权的情况。 &#x1f680; 本文旨在服务于看了别的关于匈牙利算法的文章但不甚理解的童…

【数据结构】二分查找(返回插入点)5.14

二分查找基础版 package 二分查找; public class BinarySearch { public static void main(String[] args) { // TODO Auto-generated method stub } public static int binarySearchBasic(int[] a,int target) { int i0,ja.length-1; //设置指针初值 while…

Ubuntu 命令

Ubuntu 命令速查表​ ​分类​​命令​​功能描述​​示例/常用选项​​​​文件与目录​ls列出目录内容ls -a&#xff08;显示隐藏文件&#xff09;; ls -lh&#xff08;详细列表易读大小&#xff09; cd切换目录cd ~&#xff08;主目录&#xff09;; cd ..&#xff08;上级…

Java集合框架详解与使用场景示例

Java集合框架是Java标准库中一组用于存储和操作数据的接口和类。它提供了多种数据结构&#xff0c;每种数据结构都有其特定的用途和性能特点。在本文中&#xff0c;我们将详细介绍Java集合框架的主要组成部分&#xff1a;List、Set和Queue&#xff0c;并通过代码示例展示它们的…

《Python星球日记》 第78天:CV 基础与图像处理

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、计算机视觉(CV)简介1. 什么是计算机视觉?2. 计算机视觉的应用场景3. 图像的基本属性a》像素(Pixel)b》通道(Channel)c》分辨率(Res…

LabVIEW在电子电工教学中的应用

在电子电工教学领域&#xff0c;传统教学模式面临诸多挑战&#xff0c;如实验设备数量有限、实验过程存在安全隐患、教学内容更新滞后等。LabVIEW 作为一款功能强大的图形化编程软件&#xff0c;为解决这些问题提供了创新思路&#xff0c;在电子电工教学的多个关键环节发挥着重…

【优选算法 | 字符串】字符串模拟题精选:思维+实现解析

算法相关知识点可以通过点击以下链接进行学习一起加油&#xff01;双指针滑动窗口二分查找前缀和位运算模拟链表哈希表 在众多字符串算法题中&#xff0c;有一类题目看起来没有太多算法技巧&#xff0c;却经常让人“翻车”——那就是字符串模拟题。这类题型往往不依赖复杂的数据…

虚幻引擎5-Unreal Engine笔记之Default Pawn与GamMode、Camera的关系

虚幻引擎5-Unreal Engine笔记之Default Pawn与GamMode、Camera的关系 code review! 文章目录 虚幻引擎5-Unreal Engine笔记之Default Pawn与GamMode、Camera的关系1.Default Pawn与Camera的关系1.1. Default Pawn 是什么&#xff1f;1.2. Default Pawn 的主要组件1.3. Default…

HarmonyOs开发之———UIAbility进阶

谢谢关注!! 前言:上一篇文章主要介绍开发之———使用HTTP访问网络资源:HarmonyOs开发之———使用HTTP访问网络资源-CSDN博客 代码资源:https://download.csdn.net/download/this_is_bug/90841580 一、基本概念 UIAbility 是 HarmonyOS 应用的核心组件,负责用户界面的…

java实现根据Velocity批量生成pdf并合成zip压缩包

Velocity 模版操作 用的之前写好的: 传送门 其中需要新加一个转成输入流的方法 public static InputStream convertToPdf(StringWriter stringWriter) throws IOException {//将 HTML 转为字节流byte[] htmlBytes stringWriter.toString().getBytes(StandardCharsets.UTF_8)…

SCDN能够运用在物联网加速当中吗?

在当今的科技化时代当中&#xff0c;物联网已经广泛渗透在各个领域行业当中&#xff0c;随着物联网规模的不断扩大&#xff0c;数据信息的传输速度和网络稳定性成为企业需要重视的两点因素&#xff0c;而SCDN也成为安全内容分发网络作为一种融合了内容加速和安全防护的技术&…

二程运输的干散货船路径优化

在二程运输中&#xff0c;干散货船需要将货物从一个港口运输到多个不同的目的地港口。路径优化的目标是在满足货物运输需求、船舶航行限制等条件下&#xff0c;确定船舶的最佳航行路线&#xff0c;以最小化运输成本、运输时间或其他相关的优化目标。 影响因素 港口布局与距离…

Oracle物理恢复相关注意点

如果需要恢复的数据库或者数据文件不存在&#xff0c;则需要将全量备份集RESTORE[ 将全量备份集恢复到目标数据库中&#xff0c;称之为RESTORE。]到目标数据库中&#xff0c;然后再RECOVER[ 将增量备份集或者归档日志恢复到目标数据库中&#xff0c;称之为RECOVER。]增量备份集…

C++ string小记

#include<string> using std::string;string s1; string s2 "hello" //初始化一个hello字符串 string s3(5,a) //连续5个字符a组成的串&#xff0c;即aaaaa///字符串操作int length s1.size() //.size()求字符串长度char c1 s1[1]; //从下标0开始&#xf…

自然语言处理入门级项目——文本分类(预处理)

文章目录 前言1.数据预处理1.1数据集介绍1.2数据集抽取1.3划分数据集1.4数据清洗1.5数据保存 2.样本的向量化表征2.1词汇表2.2向量化2.3自定义数据集2.4备注 结语 前言 本篇博客主要介绍自然语言处理领域中一个项目案例——文本分类&#xff0c;具体而言就是判断评价属于积极还…