Maison > Article > développement back-end > Partagez une méthode Python pour explorer les commentaires populaires sur NetEase Cloud Music
Cet article présentera en détail un exemple d'utilisation de Python pour obtenir des commentaires populaires sur NetEase Cloud Music. Il a une très bonne valeur de référence. Jetons-y un coup d'œil avec l'éditeur ci-dessous
J'ai récemment étudié le contenu lié à l'exploration de texte. On dit qu'une femme intelligente ne peut pas préparer un repas sans riz. Si vous souhaitez effectuer une analyse de texte, vous devez d'abord disposer de texte. Il existe de nombreuses façons d'obtenir du texte, par exemple en téléchargeant des documents texte prêts à l'emploi sur Internet ou en obtenant des données via des API fournies par des tiers. Mais parfois, les données que nous souhaitons ne peuvent pas être obtenues directement car il n’existe pas de canal de téléchargement direct ni d’API permettant d’obtenir les données. Alors que devons-nous faire à ce moment-là ? Une meilleure méthode consiste à utiliser un robot d'exploration Web, c'est-à-dire à écrire un programme informatique pour se faire passer pour un utilisateur afin d'obtenir les données souhaitées. Profitant de l’efficacité des ordinateurs, nous pouvons obtenir des données facilement et rapidement.
Alors comment écrire un robot ? Il existe de nombreux langagesqui peuvent être utilisés pour écrire des robots, tels que Java, php, python, etc. Personnellement, je préfère utiliser python. Parce que Python possède non seulement de puissantes bibliothèques réseau intégrées, mais également de nombreuses excellentes bibliothèques tierces. D'autres ont directement construit la roue, et nous pouvons simplement l'utiliser. Cela apporte une grande commodité à l'écriture de robots. Il n'est pas exagéré de dire que vous pouvez réellement écrire un petit robot avec moins de 10 lignes de code Python, tandis que l'utilisation d'autres langages peut vous obliger à écrire beaucoup plus de code. Être concis et facile à comprendre est un énorme avantage. avantage de Python.
Bien, sans plus tarder, passons au sujet principal d’aujourd’hui. NetEase Cloud Music est devenu très populaire ces dernières années. Je suis un utilisateur de NetEase Cloud Music et je l'utilise depuis plusieurs années. J'utilisais QQ Music et Kugou Grâce à ma propre expérience personnelle, je pense que les meilleures fonctionnalités de NetEase Cloud Music sont ses recommandations de chansons précises et ses critiques d'utilisateurs uniques (pour mémoire !!! Ce n'est pas un article doux), non. publicité ! Ce n'est que mon avis personnel, ne commentez pas ! Il y aura souvent des commentaires sous une chanson qui a reçu de nombreux likes. Couplé au fait que NetEase Cloud Music a mis dans le métro des avis d'utilisateurs sélectionnés il y a quelques jours, les avis de NetEase Cloud Music sont redevenus populaires. Par conséquent, je souhaite analyser les commentaires de NetEase Cloud et découvrir les modèles, en particulier les caractéristiques communes de certains commentaires chauds. Dans ce but, j'ai commencé à explorer les commentaires NetEase Cloud.
Python a deux bibliothèques réseau intégrées, urllib et urllib2, mais ces deux bibliothèques ne sont pas particulièrement pratiques à utiliser, nous utilisons donc ici une bibliothèque tierce bien reçue, les requêtes. À l'aide de requêtes, vous pouvez réaliser des travaux d'exploration plus complexes, tels que la configuration d'agents et la simulation de connexions avec seulement quelques lignes de code. Si pip est déjà installé, utilisez simplement les requêtes d'installation pip pour l'installer. L'adresse du document chinois est ici : http://docs.python-requests.org/zh_CN/latest/user/quickstart.html Si vous avez des questions, vous pouvez vous référer au document officiel. Il y aura une introduction très détaillée. au-dessus de. Quant aux deux bibliothèques urllib et urllib2, elles sont également très utiles, je vous les présenterai si j'en ai l'occasion dans le futur.
Avant de présenter officiellement le robot, parlons d'abord du principe de fonctionnement de base du robot. Nous savons que lorsque nous ouvrons le navigateur pour visiter une certaine URL, nous envoyons essentiellement une certaine requête au serveur après que le serveur ait reçu notre. demande, les données seront renvoyées conformément à notre demande, puis les données seront analysées via le navigateur et nous seront présentées. Si nous utilisons du code, nous devons sauter cette étape du navigateur, envoyer certaines données directement au serveur, puis récupérer les données renvoyées par le serveur pour extraire les informations souhaitées. Mais le problème est que parfois le serveur doit vérifier la requête que nous envoyons. S'il pense que notre requête est illégale, il ne renverra pas de données ou renverra des données erronées. Ainsi, afin d'éviter cette situation, nous devons parfois déguiser le programme en utilisateur normal afin d'obtenir une réponse du serveur. Comment le déguiser ? Cela dépend de la différence entre les utilisateurs accédant à une page Web via un navigateur et nous accédant à une page Web via un programme. De manière générale, lorsque nous accédons à une page Web via un navigateur, en plus d'envoyer l'URL consultée, nous enverrons également des informations supplémentaires au service, telles que des en-têtes (informations d'en-tête), etc. Ceci équivaut au certificat d'identité du demande, et le serveur le voit Avec ces données, nous saurons que nous y accédons via un navigateur normal, et les données nous seront renvoyées docilement. Notre programme doit donc être comme un navigateur, apportant ces informations qui marquent notre identité lors de l'envoi d'une requête, afin que nous puissions obtenir les données sans problème. Parfois, nous devons être connectés pour obtenir certaines données, nous devons donc simuler la connexion. Essentiellement, se connecter via le navigateur signifie publier certaines informations du formulaire sur le serveur (y compris le nom d'utilisateur, le mot de passe et d'autres informations). Une fois que le serveur les a vérifiées, nous pouvons nous connecter en douceur, quelles que soient les données. le navigateur publie, nous l'envoyons tel quel. Concernant la connexion simulée, je la présenterai spécifiquement plus tard. Bien sûr, les choses ne se passent parfois pas aussi bien, car certains sites Web ont mis en place des mesures anti-crawling. Par exemple, si l'accès est trop rapide, l'adresse IP sera parfois bloquée (généralement Douban). À ce stade, nous devons également configurer un serveur proxy, c'est-à-dire changer notre adresse IP. Si une adresse IP est bloquée, la manière de procéder spécifiquement sera discutée plus tard.
Enfin, permettez-moi de vous présenter une petite astuce qui me semble très utile dans le processus d'écriture de robots d'exploration. Si vous utilisez Firefox ou Chrome, vous avez peut-être remarqué un endroit appelé outils de développement (chrome) ou console Web (firefox). Cet outil est très utile car grâce à lui, nous pouvons voir clairement quelles informations le navigateur envoie et quelles informations le serveur renvoie lors de la visite d'un site Web. Ces informations sont la clé pour écrire un robot. Ci-dessous, vous verrez à quel point cela peut être utile.
------------------------------------------------------ --- --------La ligne de démarcation officielle de départ--------------------------------------------- ------ ----------------
Ouvrez d'abord la version Web de NetEase Cloud Music et sélectionnez une chanson pour ouvrir sa page Web. prenons comme exemple "Sunny Day" de Jay Chou. Comme le montre la figure 1 ci-dessous
Figure 1
Ensuite, ouvrez la console Web (pour Chrome, ouvrez les outils de développement, si c'est un autre navigateur (l'appareil doit être similaire), comme le montre la figure 2 ci-dessous
Figure 2
Puis à ce moment nous devons cliquer sur le réseau et effacer toutes les informations, puis cliquer sur Renvoyer (équivalent à actualiser le navigateur), afin que nous puissions voir intuitivement quelles informations le navigateur a envoyées et à quelles informations le serveur a répondu. Comme le montre la figure 3 ci-dessous
Figure 3
Les données obtenues après rafraîchissement sont telles que présentées dans la figure 4 ci-dessous :
Figure 4
Vous pouvez voir que le navigateur envoie beaucoup d'informations, alors laquelle voulons-nous ? Ici, nous pouvons faire un jugement préliminaire grâce au code d'état. Le code d'état marque l'état de la demande du serveur. Le code d'état ici est 200, ce qui signifie que la demande est normale, et 304, ce qui signifie qu'elle est anormale (il en existe de nombreux types). des codes de statut. Si vous le souhaitez, vous pouvez le rechercher vous-même (je ne parlerai pas de la signification spécifique de 304 ici). Nous n'avons donc généralement besoin d'examiner que les requêtes avec le code d'état 200. De plus, nous pouvons observer grossièrement les informations renvoyées par le serveur (ou afficher la réponse) via l'aperçu dans la colonne de droite. Comme le montre la figure 5 ci-dessous :
Figure 5
En combinant ces deux méthodes, on peut trouver rapidement la requête que l'on souhaite analyser. Notez que la colonne URL de requête dans la figure 5 est l'URL que nous souhaitons demander. Il existe deux méthodes de requête : get et post. Une autre chose sur laquelle il faut se concentrer est l'en-tête de la requête, qui contient l'agent utilisateur (informations sur le client). ), la référence (d'où sauter) et d'autres informations. Généralement, nous apporterons les informations d'en-tête, qu'il s'agisse de la méthode get ou post. Les informations d'en-tête sont présentées dans la figure 6 ci-dessous :
Figure 6
De plus, il convient de noter que : get requêtes sont généralement directs Mettre les paramètres de la requête avec ? paramètre1=valeur1¶mètre2=valeur2 etc. est envoyé sous cette forme, il n'est donc pas nécessaire d'apporter des paramètres de requête supplémentaires. Les demandes de publication doivent généralement apporter des paramètres supplémentaires au lieu de placer directement les paramètres dans l'URL, donc parfois nous devons également payer. attention à la colonne des paramètres. Après une recherche minutieuse, nous avons finalement trouvé la demande originale liée au commentaire sur http://music.163.com/weapi/v1/resource/comments/R_SO_4_186016?csrf_token=, comme le montre la figure 7 ci-dessous :
Figure 7
Cliquez sur cette requête, et nous constatons qu'il s'agit d'une requête de publication. Il y a deux paramètres dans la requête, l'un est params, et l'autre est encSecKey. Les valeurs de ces deux paramètres sont très longues et on a l'impression qu'elles sont cryptées. Comme le montre la Figure 8 ci-dessous :
Figure 8
Les données liées aux commentaires renvoyés par le serveur sont au format json, qui contient des informations très riches (telles que des informations sur les commentateurs, la date du commentaire, le nombre de likes, le contenu du commentaire, etc.), comme le montre la figure 9 ci-dessous : (En fait, hotComments est un commentaire chaud, et les commentaires sont un tableau de commentaires )
Figure 9
À ce stade, nous avons déterminé la direction, c'est-à-dire qu'il nous suffit de déterminer les deux valeurs des paramètres de params et encSecKey. Ce problème est gênant. J'ai passé un après-midi à essayer de comprendre la méthode de cryptage de ces deux paramètres, mais j'ai trouvé un modèle, http://music.163.com/weapi/v1/resource. /comments/R_SO_4_186016?csrf_token= Le nombre après R_SO_4_ est la valeur d'identification de cette chanson pour les valeurs param et encSecKey de différentes chansons, si les deux valeurs de paramètre d'une chanson telle que A sont transmises au. chanson B, alors pour un même numéro de page, ce paramètre est universel, c'est à dire que si les deux valeurs de paramètres de la première page de A sont passées aux deux paramètres de n'importe quelle autre chanson, les commentaires de la première page de la chanson correspondante peut être obtenue. Pour la deuxième page, la troisième page Les pages et ainsi de suite sont similaires. Mais malheureusement, les différents paramètres de page sont différents. Cette méthode ne peut capturer qu'un nombre limité de pages (bien sûr, il suffit de capturer le nombre total de commentaires et de commentaires populaires. Si vous souhaitez capturer toutes les données, vous devez comprendre). comment ces deux valeurs de paramètres sont cryptées. Je pensais que je ne comprenais pas, alors hier soir je suis allé à Zhihu pour chercher avec cette question, et j'ai en fait trouvé la réponse. Jusqu'à présent, nous avons fini d'expliquer comment capturer toutes les données des commentaires de NetEase Cloud Music.
Comme d'habitude, j'ai téléchargé le code en dernier, et il a fonctionné lors de mon propre test :
#!/usr/bin/env python2.7 # -*- coding: utf-8 -*- # @Time : 2017/3/28 8:46 # @Author : Lyrichu # @Email : 919987476@qq.com # @File : NetCloud_spider3.py ''' @Description: 网易云音乐评论爬虫,可以完整爬取整个评论 部分参考了@平胸小仙女的文章(地址:https://www.zhihu.com/question/36081767) post加密部分也给出了,可以参考原帖: 作者:平胸小仙女 链接:https://www.zhihu.com/question/36081767/answer/140287795 来源:知乎 ''' from Crypto.Cipher import AES import base64 import requests import json import codecs import time # 头部信息 headers = { 'Host':"music.163.com", 'Accept-Language':"zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", 'Accept-Encoding':"gzip, deflate", 'Content-Type':"application/x-www-form-urlencoded", 'Cookie':"_ntes_nnid=754361b04b121e078dee797cdb30e0fd,1486026808627; _ntes_nuid=754361b04b121e078dee797cdb30e0fd; JSESSIONID-WYYY=yfqt9ofhY%5CIYNkXW71TqY5OtSZyjE%2FoswGgtl4dMv3Oa7%5CQ50T%2FVaee%2FMSsCifHE0TGtRMYhSPpr20i%5CRO%2BO%2B9pbbJnrUvGzkibhNqw3Tlgn%5Coil%2FrW7zFZZWSA3K9gD77MPSVH6fnv5hIT8ms70MNB3CxK5r3ecj3tFMlWFbFOZmGw%5C%3A1490677541180; _iuqxldmzr_=32; vjuids=c8ca7976.15a029d006a.0.51373751e63af8; vjlast=1486102528.1490172479.21; __gads=ID=a9eed5e3cae4d252:T=1486102537:S=ALNI_Mb5XX2vlkjsiU5cIy91-ToUDoFxIw; vinfo_n_f_l_n3=411a2def7f75a62e.1.1.1486349441669.1486349607905.1490173828142; P_INFO=m15527594439@163.com|1489375076|1|study|00&99|null&null&null#hub&420100#10#0#0|155439&1|study_client|15527594439@163.com; NTES_CMT_USER_INFO=84794134%7Cm155****4439%7Chttps%3A%2F%2Fsimg.ws.126.net%2Fe%2Fimg5.cache.netease.com%2Ftie%2Fimages%2Fyun%2Fphoto_default_62.png.39x39.100.jpg%7Cfalse%7CbTE1NTI3NTk0NDM5QDE2My5jb20%3D; usertrack=c+5+hljHgU0T1FDmA66MAg==; Province=027; City=027; _ga=GA1.2.1549851014.1489469781; __utma=94650624.1549851014.1489469781.1490664577.1490672820.8; __utmc=94650624; __utmz=94650624.1490661822.6.2.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; playerid=81568911; __utmb=94650624.23.10.1490672820", 'Connection':"keep-alive", 'Referer':'http://music.163.com/' } # 设置代理服务器 proxies= { 'http:':'http://121.232.146.184', 'https:':'https://144.255.48.197' } # offset的取值为:(评论页数-1)*20,total第一页为true,其余页为false # first_param = '{rid:"", offset:"0", total:"true", limit:"20", csrf_token:""}' # 第一个参数 second_param = "010001" # 第二个参数 # 第三个参数 third_param = "00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7" # 第四个参数 forth_param = "0CoJUm6Qyw8W8jud" # 获取参数 def get_params(page): # page为传入页数 iv = "0102030405060708" first_key = forth_param second_key = 16 * 'F' if(page == 1): # 如果为第一页 first_param = '{rid:"", offset:"0", total:"true", limit:"20", csrf_token:""}' h_encText = AES_encrypt(first_param, first_key, iv) else: offset = str((page-1)*20) first_param = '{rid:"", offset:"%s", total:"%s", limit:"20", csrf_token:""}' %(offset,'false') h_encText = AES_encrypt(first_param, first_key, iv) h_encText = AES_encrypt(h_encText, second_key, iv) return h_encText # 获取 encSecKey def get_encSecKey(): encSecKey = "257348aecb5e556c066de214e531faadd1c55d814f9be95fd06d6bff9f4c7a41f831f6394d5a3fd2e3881736d94a02ca919d952872e7d0a50ebfa1769a7a62d512f5f1ca21aec60bc3819a9c3ffca5eca9a0dba6d6f7249b06f5965ecfff3695b54e1c28f3f624750ed39e7de08fc8493242e26dbc4484a01c76f739e135637c" return encSecKey # 解密过程 def AES_encrypt(text, key, iv): pad = 16 - len(text) % 16 text = text + pad * chr(pad) encryptor = AES.new(key, AES.MODE_CBC, iv) encrypt_text = encryptor.encrypt(text) encrypt_text = base64.b64encode(encrypt_text) return encrypt_text # 获得评论json数据 def get_json(url, params, encSecKey): data = { "params": params, "encSecKey": encSecKey } response = requests.post(url, headers=headers, data=data,proxies = proxies) return response.content # 抓取热门评论,返回热评列表 def get_hot_comments(url): hot_comments_list = [] hot_comments_list.append(u"用户ID 用户昵称 用户头像地址 评论时间 点赞总数 评论内容\n") params = get_params(1) # 第一页 encSecKey = get_encSecKey() json_text = get_json(url,params,encSecKey) json_dict = json.loads(json_text) hot_comments = json_dict['hotComments'] # 热门评论 print("共有%d条热门评论!" % len(hot_comments)) for item in hot_comments: comment = item['content'] # 评论内容 likedCount = item['likedCount'] # 点赞总数 comment_time = item['time'] # 评论时间(时间戳) userID = item['user']['userID'] # 评论者id nickname = item['user']['nickname'] # 昵称 avatarUrl = item['user']['avatarUrl'] # 头像地址 comment_info = userID + " " + nickname + " " + avatarUrl + " " + comment_time + " " + likedCount + " " + comment + u"\n" hot_comments_list.append(comment_info) return hot_comments_list # 抓取某一首歌的全部评论 def get_all_comments(url): all_comments_list = [] # 存放所有评论 all_comments_list.append(u"用户ID 用户昵称 用户头像地址 评论时间 点赞总数 评论内容\n") # 头部信息 params = get_params(1) encSecKey = get_encSecKey() json_text = get_json(url,params,encSecKey) json_dict = json.loads(json_text) comments_num = int(json_dict['total']) if(comments_num % 20 == 0): page = comments_num / 20 else: page = int(comments_num / 20) + 1 print("共有%d页评论!" % page) for i in range(page): # 逐页抓取 params = get_params(i+1) encSecKey = get_encSecKey() json_text = get_json(url,params,encSecKey) json_dict = json.loads(json_text) if i == 0: print("共有%d条评论!" % comments_num) # 全部评论总数 for item in json_dict['comments']: comment = item['content'] # 评论内容 likedCount = item['likedCount'] # 点赞总数 comment_time = item['time'] # 评论时间(时间戳) userID = item['user']['userId'] # 评论者id nickname = item['user']['nickname'] # 昵称 avatarUrl = item['user']['avatarUrl'] # 头像地址 comment_info = unicode(userID) + u" " + nickname + u" " + avatarUrl + u" " + unicode(comment_time) + u" " + unicode(likedCount) + u" " + comment + u"\n" all_comments_list.append(comment_info) print("第%d页抓取完毕!" % (i+1)) return all_comments_list # 将评论写入文本文件 def save_to_file(list,filename): with codecs.open(filename,'a',encoding='utf-8') as f: f.writelines(list) print("写入文件成功!") if __name__ == "__main__": start_time = time.time() # 开始时间 url = "http://music.163.com/weapi/v1/resource/comments/R_SO_4_186016/?csrf_token=" filename = u"晴天.txt" all_comments_list = get_all_comments(url) save_to_file(all_comments_list,filename) end_time = time.time() #结束时间 print("程序耗时%f秒." % (end_time - start_time))
J'ai utilisé le code ci-dessus pour exécuter et capturer deux des chansons populaires de Jay Chou "Sunny Day " (avec plus de 1,3 million de commentaires) et "Confession Balloon" (avec plus de 200 000 commentaires), le premier a duré environ 20 minutes et le second a duré plus de 6 600 secondes (soit près de 2 heures). Les captures d'écran sont les suivants :
Notez que je les ai séparés par des espaces. Chaque ligne a un identifiant d'utilisateur, un pseudo d'utilisateur, un avatar d'utilisateur, une adresse, temps de commentaire, nombre total de likes et contenu.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!