发布时间:2025-06-05
浏览次数:0
她和我分手,说不甘心这辈子只和一个平庸男人一起。
我黯然去别城打拼,十年后事业有成,依然爱她。
也听说她嫁给有钱人生活安逸但不快乐。
后来我受邀出席了一场同学聚会,得知她也会出席,我便特意打扮得狼狈不堪。有人对此感到不解,我便解释道:
我要使她确信,当年她作出的离我而去之决定是明智的,如此一来,她现在的日子将会更加快乐。
——网易云音乐用户 @炸猪排-超人 在歌曲《涩》下的评论
网易云音乐作为音乐领域的新兴力量,不仅拥有丰富的音乐资源,还另辟蹊径,开创了音乐评论这一新领域。在这里,众多用户纷纷分享着他们真实或虚构的生活点滴,其中不乏感人至深的故事,还有不少评论成为了年度的流行金句,而许多引人入胜的故事也隐藏在这些音乐评论之中。
恰逢一位同学需要完成数据挖掘的作业,其目标是对网易云音乐上名为“民谣200首【精选】”的歌单里每首歌曲的精彩评论进行文本分析。她向我寻求协助,而我此前未曾涉足网易云音乐。于是,我对此进行了探索,发现了几个引人入胜的细节,因此记录下来。
本推送主要阐述数据获取的技术,亦即资源挖掘的策略,而对于数据深层次价值的挖掘,即富含矿藏的部分,研究者需根据研究目标自行进行深入挖掘。
图1
歌单页面(部分),这个歌单共收录200首歌(红框部分)
图2
歌单页面(部分):歌曲的排列
获取歌单中的歌曲信息
为了搜集每首歌曲的评价,我们需先着手获取歌单中每首歌曲的具体链接,我将其称作“一级页面信息提取”。这个过程相对简便,只需通过查看网页源代码便可轻松实现。
图3
中右键查看源代码
可以观察到,在点击右键后,会出现两个“查看源代码”的选项,分别对应网页本身和框架内容,点击后可利用歌单中的歌曲名称进行检索。实际上,我们浏览到的歌单页面上的“歌曲列表”是嵌入在网页背景中的框架。在网易云音乐的其他歌单中,背景网页的源代码大体相同,变化之处仅在于包含“歌曲列表”的框架部分。
图4
框架的源代码
如图4所展示,在框架的源代码中,每首歌曲的相关数据均被整合于同一区域。我的任务便是解析该页面,从中提取所需信息。这一过程相当基础,我主要运用了3.6版本中的两个模块来完成。最终,我将提取的数据以json格式保存,以便于后续的处理工作。
图5
一级页面抓取代码
图5展示了抓取一级页面的代码,其操作简便易懂。观察最终的打印输出,我们可以看到:总共成功抓取了200首歌曲的相关信息,这与“歌曲列表”中展示的数量完全一致。
图6
一级页面抓取结果(部分)
图7
一级页面抓取结果(写入文件,json格式)
歌曲页面(二级页面)参数分析
通过一级页面的“link”字段,我们能够进入每首歌曲的独立页面。以歌单中的首曲《涩》,演唱者为纣王老胡为例,理论上,精彩评论的相关数据应当呈现于网页的源代码之中。然而,无论是网页本身还是其框架代码,均未发现评论数据的踪迹。因此,我们必须深入数据传输环节,仔细观察网络请求,以探寻含有评论数据的响应究竟藏身何处。
图8
歌曲《涩》的评论区,抓取目标是“精彩评论”(红框部分)
在精彩的评论里,众用户的经历与情感深得人心,网易云音乐的评论区域常常充满智慧之语,甚至一度风靡整个地铁车厢,其研究价值不言而喻。为了监测数据流动,我们必须借助“检查”——“”这一功能。通过它,我们可以对HTTP请求后获取的资源信息进行深入分析,诸如状态、资源种类、处理时长以及响应的详细信息等。
通常情况下,此类无法在源代码中查找到的信息,我们会借助AJAX技术进行加载,通常是通过XHR接口来实现与HTTP/HTTPS协议之间的通信。因此,在审查过程中,可以直接选取“XHR”选项,从而提高审查的效率。
图9
歌曲《涩》页面加载时通过XHR接口的网络响应
在XHR接口的每个响应资源中点击,你可以在右侧找到那些包含评论数据的资源,这些评论数据呈现为“”这样的格式,并且遵循标准的json格式,其中包含(一般评论)以及(优秀评论)。
图10
评论数据所处位置,红框部分为精彩评论
转换至该界面,我们能够观察到该资源的请求类型为POST,而所需参数则存储在表单数据部分,具体包括:以及。
图11
发送的是POST请求(红框所示)
图12
请求中两个关键参数:, (红框所示)
乍看之下,这两个参数显得相当繁杂,似乎缺乏任何明显的逻辑性。然而,仅从它们的名称就能推断,这些数据必然是经过加密处理的。当前的任务便是探寻这两个参数究竟是如何被生成的。自然而然地,我们会想要探究发出这些请求的源头究竟是谁。鉴于XHR通常是通过进行网络通信的,因此这个源头很可能是由一个脚本所发起。
图13
查看评论数据请求的发出者
如图13所展示,在信息窗口关闭之后,我们能够观察到评论数据的发布者标识为core.js;当点击进入core.js文件时,我们会发现该网站对JS代码进行了压缩,其密集程度令人眼花缭乱。在这种情况下,我采取的措施是复制代码,并借助在线工具或插件对其进行优化,从而提高代码的可读性。
图14
使用提升core.js代码可读性
将改进后的程序代码复制至相应位置后,可观察到代码量已超过25,000行。通过直接依据两个重要参数的名称进行检索,不难在图15所展示的位置找到这两个参数。
图15
关键参数出现的地方
显而易见,这两个参数均与截图中的bAQ8I存在关联,同时bAQ8I这一变量的计算过程涉及四个关键参数,分别是JSON的j4n以及biZ3x。
‘流泪’, ‘强’
以泪水、力量、关怀、少女、惊慌、欢笑等元素为参照,实在难以揣摩网易云音乐背后的程序员哥哥们所经历的种种。
若需从代码中推算出这些参数,几乎是不现实的,因为过程过于复杂;稍加搜索,就会发现某个参数被提及数百次。相对而言,一种较为经济的方法是直接查阅参数的输出结果。为此,需对core.js进行修改,并拦截网页的请求,将其重新导向至我修改后的本地资源。如此一来,我只需通过执行..log(参数名称)命令,便能够查看到参数的相关信息。
拦截请求重定向这类操作sublime text 2 js format,仅凭抓包工具是无法完成的。我曾在其中尝试过,能够明显观察到每次访问歌曲页面时的请求与响应情况,但在实际进行请求拦截和资源替换的环节,操作起来并不便捷。无奈之下,我只能使用自己的电脑,寻求那神奇的解决方案,当然,也可以通过Mono在操作系统上运行.exe文件,但这整个过程相对繁琐。
这实际上是一种位于服务器与客户端之间的HTTP代理,它能够捕捉并记录客户端与服务器间的HTTP交互,同时支持对特定请求进行断点设置和调试操作,是进行Web调试的重要工具之一。在此,我主要利用了其提供的功能,该功能能够实现请求的拦截与重定向。经过重定向后,实际上请求的目标将变为本地文件(即我修改过的core.js文件)或是内置的响应内容。
我的电脑上装有版本4,在使用软件之前,建议您先点击界面左上方的选项,将所有应用项目全部勾选(即点击“全部”),这样做可以确保不会遗漏任何HTTP请求。
图16
设置
打开《涩》这首歌曲的网页后,你会发现Web界面上详细记录了与之相关的HTTP请求信息,这些信息涵盖了状态码、协议类型、主机名以及链接等多个方面。
图17
中Web 面板的记录
目前需要对core.js文件进行一些调整,所涉及的改动相当简便,只需将bAQ8I变量在计算时涉及的四个关键参数直接输出至控制台,具体修改步骤如下:
图18
core.js修改如红框所示
由于需要同时展示若干个参数,以避免信息间的相互干扰,我们加入了辅助标识,例如使用..log(1)这样的标记来区分。
为了获取core.js的完整代码,我们必须在网页的源代码中进行查找,很容易就能找到js文件的完整路径是:
禁止访问该链接,请勿下载或使用名为“core.js”的文件,该文件位于“http://s3.music.126.net/sep/s/2/”路径下。
图19
完整js路径寻找
在接下来的操作中,我们需要设定新的规则。具体步骤如下:首先,根据图20的指引,进入文件替换环节。然后,在弹出的选项中,选择“查找文件”。最后,挑选出经过修改的core.js文件。
图20
建立重定向规则
制定好规则之后,参照图21的指示,需要进行三个步骤的配置:首先,勾选上方的三个复选框,然后点击“保存”,最后执行“进入”操作。
图21
建立规则后的三步操作
返回至歌曲界面后,请先进行页面缓存清除操作,接着刷新页面。清除缓存的具体步骤是在页面中右键点击,选择“清除缓存”并确认,之后切换至相应界面,刷新网页,即可看到所需的结果输出。
图22
控制台()输出结果示意
如图22,从上到下,依此打印出四个参数的值。
第一个参数
这个JSON格式的参数中,末尾的空字段“rid”和“total”是否存在,实际上并不影响结果,这一点是我经过多次实验后得出的结论。
第二个参数
,尝试多次后可以发现:这串数字在任何歌曲页面都不变。
第三个参数
,其实这个参数在任何页面也都一致。
第四个参数
,嗯!还是一致的。
我在此顺便进行了bAQ8I的打印操作,但发现其显示结果在各个页面间存在差异。据此,我们可以合理推测,变量bAQ8I可能已经经过了随机化处理。接下来,我们只需弄清楚该变量的计算方法,即了解其具体设置是怎样的。
在core.js文件中进行查找,我们会发现它实际上是一个函数。这个函数的运作机制相对复杂,它等同于函数d,而函数d本身又与另外几个函数——a、b、c有着关联。
图23
.部分
如图23所示,变量等于函数d,而在该函数中,所传递的参数涵盖了d、e、f、g四个部分。在函数的运算规则里,i与函数a存在关联。显而易见,当i等于a(16)时,函数a将输出一个长度为16的随机字符串,其取值范围与函数a所展示的内容一致。
”89”.
"爱心", "女孩", "惊恐", "大笑"
h.等于b(h., i),这表示对先前加密过的内容进行了进一步的加密处理,采用的加密标准是i,即一个由16个字符组成的随机字符串。在函数b的细节中,f = .AES.(e, c, {iv: d, mode: .mode.CBC})揭示了密钥的偏移值为“60708”,而加密所采用的模式则是CBC。
至此,我们已对参数的来源进行了详尽剖析,正如图18所展示的那样:bAQ8I.,,我们成功揭示了其生成机理,这相当于掌握了POST请求中至关重要的参数之一。
在POST方法的第二个重要参数中,如图23所示的函数d中,h等于c函数对i、e和f的运算结果,其中i是前面提到的随机字符串。为了简化问题,我们可以假设i由16个'0'或者16个'a'组成。在这种情况下,无论e和f的值如何变化,将它们代入c函数后得到的结果都将保持一致。
歌曲页面(二级页面)代码
在写二级页面的代码之前,需要弄清楚,在
禁止对特定内容进行修改,标识为空,计数为0,确认总数量为真实值,每页限制显示20项。
""}
在浏览评论的第一页时,若total值为真,且亮点评论仅存在于第一页,那么便无需进行任何调整。考虑到评论页数与所需内容直接相关sublime text 2 js format,我仅需关注第一页的信息,因此将页数保持为零。此外,rid后面的数字代表的是歌曲的唯一标识符,正如之前所述,这一部分可以留空。这些做法都是基于对多个歌曲页面及其不同评论页数进行深入分析后得出的经验。
在多次出现的随机字符串中,我将字符i设定为16个连续的'a',如此一来,它们所代表的就是:
这一系列字符的获取方式与之前所述相同,同样是通过对core.js进行修改并拦截请求重定向而实现的。
经过详细梳理后,完整代码就很容易写出了,具体如下:
图24
代码片段1:引入库
图25
代码片段2:请求头与类中的固定参数
图26
代码片段3中,类内的函数包括获取数据的功能;同时,还包含一个加密函数,该函数借鉴了知乎用户@洛克提供的代码,具体实现是将函数b进行具体化处理。
图27
代码片段4:该类中的函数负责对请求返回的json格式数据进行解析,完整的数据信息可以在相关页面进行查阅。
图28
代码片段5:实例化并且将结果写入文件
图29
打印结果片段,输出歌曲名称、歌曲ID、精彩评论数量
最终,可以将先前搜集到的歌单资料以及当前搜集到的精彩评论内容进行整合。
图30
合并两个文件的代码
图31
文件合并后的结果
总 结
复杂爬虫的关键在于对数据传输进行严谨的分析,需从HTTP请求与响应入手,并利用相关工具进行详尽的调试;遇到数据加密情况(例如微博、网易云音乐),还需对加密技术、RSA组件以及相关模块有较高的熟练度。
作者 | 传播研究方法硕士研究生 罗晨
审阅 | 沈浩老师
如有侵权请联系删除!
Copyright © 2023 江苏优软数字科技有限公司 All Rights Reserved.正版sublime text、Codejock、IntelliJ IDEA、sketch、Mestrenova、DNAstar服务提供商
13262879759
微信二维码