Der in diesem Artikel geteilte Inhalt befasst sich mit der Verwendung von Python zum Crawlen beliebter Kommentare zu NetEase Cloud Music. Er hat einen gewissen Referenzwert.
Vorwort
Vor kurzem habe ich Inhalte im Zusammenhang mit Text Mining studiert Eine kluge Frau kann ohne Reis keine Mahlzeit zubereiten. Um eine Textanalyse durchführen zu können, benötigen Sie zunächst Text. Es gibt viele Möglichkeiten, Text zu erhalten, z. B. das Herunterladen vorgefertigter Textdokumente aus dem Internet oder das Abrufen von Daten über von Dritten bereitgestellte APIs. Aber manchmal können die gewünschten Daten nicht direkt abgerufen werden, weil es keinen direkten Download-Kanal oder keine API gibt, über die wir die Daten erhalten könnten. Was sollen wir also zu diesem Zeitpunkt tun? Eine bessere Möglichkeit ist die Verwendung eines Webcrawlers, der ein Computerprogramm schreibt, das sich als Benutzer ausgibt, um die gewünschten Daten zu erhalten. Durch die Leistungsfähigkeit von Computern können wir Daten einfach und schnell abrufen.
Über Crawler
So schreibt man einen Crawler Wollstoff? Es gibt viele Sprachen, die zum Schreiben von Crawlern verwendet werden können, wie Java, PHP, Python usw. Ich persönlich bevorzuge die Verwendung von Python. Da Python nicht nur über eine integrierte leistungsstarke Netzwerkbibliothek verfügt, sondern auch über viele hervorragende Bibliotheken von Drittanbietern, können wir es einfach verwenden. Dies bringt großen Komfort beim Schreiben von Crawlern. Es ist keine Übertreibung zu sagen, dass Sie tatsächlich einen kleinen Crawler mit weniger als 10 Zeilen Python-Code schreiben können, während Sie bei der Verwendung anderer Sprachen möglicherweise viel mehr Code schreiben müssen. Seien Sie prägnant und Leicht zu verstehen ist ein großer Vorteil von Python .
Okay, ohne weitere Umschweife, kommen wir heute zum Hauptthema. NetEase Cloud Music ist in den letzten Jahren sehr beliebt geworden. Ich bin ein Benutzer von NetEase Cloud Music und verwende es seit mehreren Jahren. Ich habe in der Vergangenheit QQ Music und Kugou verwendet. Aus eigener Erfahrung denke ich, dass die besten Eigenschaften von NetEase Cloud Music die genauen Songempfehlungen und einzigartigen Benutzerrezensionen sind (Formelle Aussage!!! Dies ist kein weicher Artikel, Keine Werbung! Es ist nur meine persönliche Meinung, bitte nicht kritisieren! Oft gibt es unter einem Lied einige Kommentare, die viele Likes erhalten haben. In Verbindung mit der Tatsache, dass NetEase Cloud Music vor einigen Tagen ausgewählte Benutzerbewertungen in die U-Bahn gestellt hat, sind die Bewertungen von NetEase Cloud Music wieder populär geworden. Daher möchte ich die Kommentare von NetEase Cloud analysieren und die Muster, insbesondere die gemeinsamen Merkmale einiger heißer Kommentare, entdecken. Zu diesem Zweck habe ich mit dem Crawlen von NetEase Cloud-Kommentaren begonnen.
Netzwerkbibliothek
Python verfügt über zwei integrierte Netzwerkbibliotheken, urllib und urllib2, aber diese beiden Bibliotheken sind nicht besonders bequem zu verwenden, daher verwenden wir hier eine gut angenommene Bibliothek eines Drittanbieters Anfragen. Mithilfe von Anfragen können Sie mit nur wenigen Codezeilen komplexere Crawler-Aufgaben wie das Einrichten von Agenten und das Simulieren von Anmeldungen erledigen. Wenn pip bereits installiert ist, verwenden Sie einfach Pip-Installationsanfragen, um es zu installieren.
Die chinesische Dokumentadresse finden Sie hier: http://docs.python-requests.org/zh_CN/latest/user/quickstart. html
Wenn Sie Fragen haben, können Sie sich an wenden Die offizielle Dokumentation oben Es wird eine sehr detaillierte Einführung geben. Die beiden Bibliotheken urllib und urllib2 sind ebenfalls sehr nützlich. Ich werde sie Ihnen bei Gelegenheit vorstellen.
Funktionsprinzip
Bevor wir offiziell mit der Einführung des Crawlers beginnen, sprechen wir zunächst über die Grundlagen Wir wissen, dass wir, wenn wir den Browser öffnen, um eine bestimmte URL zu besuchen, im Wesentlichen eine bestimmte Anfrage an den Server senden . Nachdem der Server unsere Anfrage erhalten hat, gibt er die Daten entsprechend zurück Unsere Anfrage, und leiten Sie sie dann durch den Browser. Analysieren Sie diese Daten und präsentieren Sie sie uns.
Wenn wir den Code verwenden , müssen wir den Browser-Schritt überspringen und direkt zum Senden gehen Wir übertragen bestimmte Daten an den Server und rufen dann die vom Server zurückgegebenen Daten ab, um die gewünschten Informationen zu extrahieren.
Aber das Problem ist, dass der Server manchmal die von uns gesendete Anfrage überprüfen muss. Wenn er denkt, dass unsere Anfrage illegal ist, werden keine Daten angezeigt zurückgegeben, andernfalls werden falsche Daten zurückgegeben. Um diese Situation zu vermeiden, müssen wir manchmal das Programm als normalen Benutzer tarnen, um erfolgreich eine Antwort vom Server zu erhalten.
Wie kann man es verbergen?
Dies hängt vom Unterschied zwischen Benutzern, die über einen Browser auf eine Webseite zugreifen, und uns, die über ein Programm auf eine Webseite zugreifen, ab.
Im Allgemeinen werden beim Zugriff auf eine Webseite über einen Browser zusätzlich zum Senden der besuchten URL zusätzliche Informationen gesendet an den Dienst. Informationen wie Header (Header-Informationen) usw., die dem Identitätszertifikat der Anfrage entsprechen, wissen, dass wir über einen normalen Browser darauf zugreifen. und es wird die Daten gehorsam zurückgeben.
Simulierte Anmeldung
Unser Programm muss also wie ein Browser sein und diese Informationen, die unsere Identität kennzeichnen, beim Senden einer Anfrage bereitstellen, damit wir die Daten reibungslos abrufen können. Manchmal müssen wir angemeldet sein, um einige Daten zu erhalten, also müssen wir die Anmeldung simulieren.
Im Wesentlichen bedeutet die Anmeldung über den Browser, einige Formularinformationen an den Server zu senden (einschließlich Benutzername, Passwort und andere Informationen, nachdem der Server dies überprüft hat). Wir können uns problemlos anmelden, und das Gleiche gilt für die Anwendung. Wir können einfach alle Daten senden, die der Browser so sendet, wie sie sind.
Über die simulierte Anmeldung werde ich später vorstellen. Natürlich läuft es manchmal nicht so reibungslos, da einige Websites Anti-Crawling-Maßnahmen eingerichtet haben. Wenn der Zugriff beispielsweise zu schnell erfolgt, wird die IP-Adresse manchmal blockiert (typischerweise Douban). Zu diesem Zeitpunkt müssen wir noch einen Proxyserver einrichten, d. h. unsere IP-Adresse ändern. Wie das konkret geht, wird später besprochen.
Tipps
Lassen Sie mich abschließend noch einen kleinen Trick vorstellen, der meiner Meinung nach beim Schreiben eines Crawlers sehr nützlich ist. Wenn Sie Firefox oder Chrome verwenden, ist Ihnen möglicherweise ein Ort namens Entwicklertools (Chrome) oder Webkonsole (Firefox) aufgefallen. Dieses Tool ist sehr nützlich, da wir damit klar erkennen können, welche Informationen der Browser sendet und welche Informationen der Server beim Besuch einer Website zurückgibt. Diese Informationen sind der Schlüssel zum Schreiben eines Crawlers. Unten sehen Sie, wie nützlich es sein kann.
So crawlen Sie Kommentare
Öffnen Sie zunächst die Webversion von NetEase Cloud Music und wählen Sie einen Song aus, um ihn zu öffnen Webseite, hier nehme ich Jay Chous „Sunny Day“ als Beispiel. Wie unten gezeigt:
Öffnen Sie als Nächstes die Webkonsole (öffnen Sie die Entwicklertools für Chrome, es sollte für andere Browser ähnlich sein), wie unten gezeigt:
Dann müssen wir zu diesem Zeitpunkt auf das Netzwerk klicken, alle Informationen löschen und dann auf „Erneut senden“ klicken (entspricht dem Aktualisieren des Browser), Auf diese Weise können wir intuitiv erkennen, welche Informationen der Browser sendet und auf welche Informationen der Server antwortet. Wie unten gezeigt:
Die nach der Aktualisierung erhaltenen Daten sind wie folgt
Sie können sehen, dass der Browser viele Informationen sendet, also welche tun wir wollen? Was willst du? Hier können wir anhand des Statuscodes eine vorläufige Beurteilung vornehmen. Der Statuscode markiert den Status der Serveranfrage. Hier bedeutet Statuscode 200, dass die Anfrage normal ist, während 304 bedeutet, dass eine Anomalie vorliegt (Es gibt viele Arten von Statuscodes. Wenn Sie mehr darüber erfahren möchten, können Sie selbst danach suchen. Die spezifische Bedeutung von 304 wird hier nicht erwähnt) . Daher müssen wir uns im Allgemeinen nur Anfragen mit dem Statuscode 200 ansehen. Außerdem können wir durch die Vorschau in der rechten Spalte grob beobachten, welche Informationen der Server zurückgibt (oder die Antwort anzeigen). Wie unten gezeigt:
By Durch die Kombination dieser beiden Methoden können wir schnell die Anfrage finden, die wir analysieren möchten. Beachten Sie, dass die Anforderungs-URL-Spalte in Abbildung 5 die URL ist, die wir anfordern möchten. Es gibt zwei Anforderungsmethoden: get und post Eine weitere Sache, auf die man sich konzentrieren muss, ist der Anforderungsheader, der den Benutzer enthält. Agent (Client-Informationen), Referenz (woher man springen soll) und andere Informationen Im Allgemeinen liefern wir die Header-Informationen, unabhängig davon, ob es sich um die Get- oder Post-Methode handelt. Die Header-Informationen sind wie folgt:
Darüber hinaus ist Folgendes zu beachten: Bei Get-Anfragen werden die Anforderungsparameter im Allgemeinen direkt in geändert? Parameter1=Wert1&Parameter2=Wert2 usw. werden in dieser Form gesendet, sodass keine zusätzlichen Anforderungsparameter erforderlich sind, während Post-Anfragen im Allgemeinen zusätzliche Parameter mitbringen müssen, anstatt die Parameter direkt in der URL zu platzieren Manchmal müssen wir immer noch auf die Parameterspalte achten. Nach sorgfältiger Suche haben wir schließlich die ursprüngliche kommentarbezogene Anfrage unter http://music.163.com/weapi/v1/resource/comments/R_SO_4_186016?csrf_token= Diese Anfrage gefunden Darunter, wie unten gezeigt:
Klicken Sie auf diese Anfrage Wir haben festgestellt, dass die Anfrage zwei Parameter enthält, einen Parameter und einen encSecKey. Die Werte dieser beiden Parameter sind sehr lang und es fühlt sich an, als wären sie verschlüsselt. Wie unten gezeigt:
Die vom Server zurückgegebenen kommentarbezogenen Daten liegen im JSON-Format vor und enthalten sehr umfangreiche Informationen (z. B. Informationen zum Kommentator, Kommentardatum, Anzahl der Likes, Kommentarinhalt usw.), wie in Abbildung dargestellt 9 unten: (Tatsächlich sind hotComments heiße Kommentare und Kommentare sind eine Reihe von Kommentaren)
An diesem Punkt haben wir die Richtung festgelegt, das heißt, wir müssen nur die Werte der beiden Parameter params und encSecKey bestimmen. Dieses Problem hat mich den ganzen Nachmittag beschäftigt Ich habe schon lange daran gearbeitet, aber ich kann diese beiden Verschlüsselungsmethoden immer noch nicht herausfinden, aber ich habe ein Muster entdeckt, http://music.163.com/weapi/v1/resource/comments /R_SO_4_186016?csrf_token= in R_SO_4_ Die Zahl nach ist der ID-Wert des Songs. Für die Parameter- und encSecKey-Werte verschiedener Songs, wenn die beiden Parameterwerte Wenn ein Lied wie A an Lied B übergeben wird, ist dieser Parameter für dieselbe Seitennummer universell, dh wenn die beiden Parameterwerte der ersten Seite von A an die beiden Parameter übergeben werden Für jedes andere Lied können die Kommentare der ersten Seite des entsprechenden Liedes abgerufen werden. Für die zweite Seite gilt das Gleiche für drei Seiten und so weiter.
Aber leider verschiedene Seitenparameter sind unterschiedlich, diese Methode kann nur begrenzte Seiten erfassen (natürlich ist das so). genug, um die Gesamtzahl der Kommentare und beliebten Kommentare zu erfassen. Wenn Sie alle Daten erfassen möchten, müssen Sie die Verschlüsselungsmethode dieser beiden Parameterwerte verstehen.
Ich dachte, ich hätte es nicht verstanden, also bin ich gestern Abend zu Zhihu gegangen, um nach dieser Frage zu suchen, und habe tatsächlich die Antwort gefunden. @ Flat-chested Little Fairy Dieser Freund hat ausführlich erklärt, wie man den Verschlüsselungsprozess dieser beiden Parameter knackt. Ich habe ihn recherchiert und festgestellt, dass er immer noch etwas kompliziert ist. Ich habe ihn gemäß der von Freund , alle Kommentare erfolgreich erhalten. Ich möchte der kleinen Fee Zhihu@flat-chested meinen Dank aussprechen.
Bisher haben wir erklärt, wie alle Daten der Kommentare von NetEase Cloud Music erfasst werden. Wie üblich habe ich den Code zuletzt hochgeladen und er hat in meinem eigenen Test funktioniert:
#!/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: 网易云音乐评论爬虫,可以完整爬取整个评论 部分参考了@平胸小仙女的文章 来源:知乎 ''' 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 用户昵称 用户头像地址 评论时间 点赞总数 评论内容") 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"" hot_comments_list.append(comment_info) return hot_comments_list # 抓取某一首歌的全部评论 def get_all_comments(url): all_comments_list = [] # 存放所有评论 all_comments_list.append(u"用户ID 用户昵称 用户头像地址 评论时间 点赞总数 评论内容") # 头部信息 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"" 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))
Ich bin mit dem obigen Code gelaufen und habe zwei von Jay Chous beliebten Songs „Sunny Day“ aufgenommen. (mit mehr als 1,3 Millionen Kommentaren) und „Confession Balloon“ (mit mehr als 200.000 Kommentaren), ersteres dauerte etwa 20 Minuten und letzteres dauerte mehr als 6.600 Sekunden (also fast 2 Stunden). wie folgt:
Beachten Sie, dass ich sie durch Leerzeichen getrennt habe, Jede Zeile hat Benutzer-ID, Benutzer-Spitzname, Benutzer-Avatar-Adresse, Kommentarzeit, Gesamtzahl der Likes, Kommentarinhalt Diese Inhalte. Schüler Achten Sie beim Ausführen des zu erfassenden Codes darauf, nicht zu viele Threads zu öffnen und den NetEase Cloud-Server zu stark zu belasten (Es gab eine Zeitspanne, in der der Server Daten sehr zurückgab langsam. Ich weiß nicht, ob es eine Einschränkung ist. Ich habe es besucht und es ging mir später besser. Möglicherweise führe ich später selbst eine visuelle Analyse der Kommentardaten durch, also bleiben Sie dran! Anhang: Diese herzerwärmenden Kommentare
Das obige ist der detaillierte Inhalt vonSo verwenden Sie Python zum Crawlen beliebter Kommentare zu NetEase Cloud Music. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!