這篇文章主要為大家介紹了關於Python3實戰之爬蟲抓取網易雲音樂熱評的相關資料,文中透過範例程式碼介紹的非常詳細,對大家的學習或工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。
前言
之前剛剛入門python爬蟲,大概有半個月沒有寫python了,都快遺忘了。於是準備寫個簡單的爬蟲練練手,我覺得網易雲音樂最優特色的就是其精準的歌曲推薦和獨具特色的用戶評論,於是寫了這個抓取網易雲音樂熱歌榜裡的熱評的爬蟲。我也是剛入門爬蟲,有什麼意見和問題歡迎提出,大家一起一起進步。
廢話就不多說了~下面來一起看看詳細的介紹吧。
我們的目標是爬取網易雲中的熱歌排行榜中所有歌曲的熱門評論。
這樣既可以減少我們需要爬取的工作量,又可以保存到高品質的評論。
實作分析
首先,我們開啟網易雲網頁版,如圖:
點擊排行榜,然後點擊左側雲音樂熱歌榜,如圖:
#我們先隨便打開一個歌曲,找到如何抓取指定的歌曲的熱門歌評的方法,如圖,我選了一個最近我比較喜歡的歌曲為例:
進去後我們會看到歌評就在這個頁面的下面,接下來我們就要想辦法取得這些評論。
接下來開啟web控制台(chrom的話開啟開發者工具,如果是其他瀏覽器應該也是類似),chrom下按F12,如圖:
選則Network,然後我們按F5刷新一下,刷新之後得到的資料如下圖所示:
#可以看到瀏覽器發送了非常多的信息,那麼哪一個才是我們想要的呢?這裡我們可以透過狀態碼做一個初步的判斷,status code(狀態碼)標誌了伺服器請求的狀態,這裡狀態碼為200即表示請求正常,而304則表示不正常(狀態碼種類非常多,如果要想詳細了解可以自行搜索,這裡不說304具體的含義了)。所以我們通常只用看狀態碼為200的請求就可以了,還有就是,我們可以透過右邊欄的預覽來粗略觀察伺服器回傳了什麼資訊(或查看回應)。透過這兩種方法結合一般我們就可以快速找到我們想要分析的請求。透過重複的查找,終於找到了含有歌評的請求,如圖:
可能截圖在CSDN上不是很清楚,我們在一個Name為R_SO_4_489998494 ?csrf_token=
的POST請求中找到了包含這首歌的歌評。我們把這個分塊截圖發出來,這樣可以看的清楚一些:
請求基本資訊:
我們再看一下提交的表單數據,我們會發現表單中需要填兩個數據,名稱為params和encSecKey。後面緊接的是一大串字符,換幾首歌會發現,每首歌的params和encSecKey都是不一樣的,因此,這兩個數據可能經過一個特定的算法進行加密過的。
伺服器返回的和評論相關的資料為json格式的,裡面含有非常豐富的資訊(例如有關評論者的信息,評論日期,點讚數,評論內容等等),其中hotComments就是我們要找的熱門評論,總共15條,如圖所示:
至此,我們已經確定了方向了,即只需要確定params和encSecKey這兩個參數值即可。但是這兩個參數是經過特定的演算法進行加密的,該怎麼辦呢?我發現了一個規律,http://music.163.com/weapi/v1/resource/comments/R_SO_4_489998494?csrf_token= 中R_SO_4_後面的數字就是這首歌的id值,而對於不同的歌曲的param和encSecKey值,如果把一首歌例如A的這兩個參數值傳給B這首歌,那麼對於相同的頁數,這種參數是通用的,即A的第一頁的兩個參數值傳給其他任何一首歌的兩個參數,都可以獲得相應歌曲的第一頁的評論,對於第二頁,第三頁等也是類似。
而我們其實只需要取得第一頁的15條熱門評論,所以我們只需要隨便找一首歌,將這首歌第一頁中的該請求中的params和encSecKey這兩個參數值複製下來,就可以使用了。
關於這兩個參數如何解密,強大的知乎上其實已經有答案的了,有興趣的朋友可以進去看一下(https://www.zhihu.com/question/ 36081767),我們在這裡就只需要用我們這種偷懶的辦法就可以完成需求了,xixi。
到此為止,我們如何抓取網易雲音樂的熱門評論已經分析完了,我們再分析一下如何獲取雲音樂熱歌榜中所有歌曲的信息。
我們需要取得雲端音樂熱歌榜中的所有歌曲的歌曲名稱和對應的id值。
跟上面的分析步驟類似,我們先進入熱歌榜的網址,如圖:
按F12,進入WEB工作台,如圖:
我們在一個名為toplist?id=3778678的GET請求中,找到了該榜單的所有歌曲資訊。
請求對應的資訊如圖:
我們預覽一下該請求回傳的結果,如圖:
我們在程式碼的第524行我們找到了包含歌曲資訊的程式碼,如圖:
因此,我們只需要將該請求的程式碼中,將包含資訊的程式碼篩選出來。
我們在這裡使用正規表示式進行資料篩選。
透過觀察特點,我們可以透過兩次正規表示式的篩選,將我們需要的歌曲資訊擷取出來。
第一次正規表示式我們將該請求傳回的所有程式碼中,提取出第525行程式碼。
第一次正規表示式如下:
<ul class="f-hide"> <li> <a href="/song\?id=\d*?" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >.*</a> </li> </ul>
第二次正規表示式我們將該第524行中我們需要的歌曲資訊擷取出來,我們需要歌曲的歌名和id,對應的正規表示式如下:
取得歌名:
<li><a href="/song\?id=\d*?" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >(.*?)</a></li>
取得歌曲的id:
<li><a href="/song\?id=(\d*?)" rel="external nofollow" rel="external nofollow" >.*?</a></li>
到此,我們整個過程已經分析完了,上程式碼看具體細節~~
程式碼如下:
##
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import re import urllib.request import urllib.error import urllib.parse import json def get_all_hotSong(): #获取热歌榜所有歌曲名称和id url='http://music.163.com/discover/toplist?id=3778678' #网易云云音乐热歌榜url html=urllib.request.urlopen(url).read().decode('utf8') #打开url html=str(html) #转换成str pat1=r'<ul class="f-hide"><li><a href="/song\?id=\d*?">.*</a></li></ul>' #进行第一次筛选的正则表达式 result=re.compile(pat1).findall(html) #用正则表达式进行筛选 result=result[0] #获取tuple的第一个元素 pat2=r'<li><a href="/song\?id=\d*?">(.*?)</a></li>' #进行歌名筛选的正则表达式 pat3=r'<li><a href="/song\?id=(\d*?)">.*?</a></li>' #进行歌ID筛选的正则表达式 hot_song_name=re.compile(pat2).findall(result) #获取所有热门歌曲名称 hot_song_id=re.compile(pat3).findall(result) #获取所有热门歌曲对应的Id return hot_song_name,hot_song_id def get_hotComments(hot_song_name,hot_song_id): url='http://music.163.com/weapi/v1/resource/comments/R_SO_4_' + hot_song_id + '?csrf_token=' #歌评url header={ #请求头部 'User-Agent':'Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36' } #post请求表单数据 data={'params':'zC7fzWBKxxsm6TZ3PiRjd056g9iGHtbtc8vjTpBXshKIboaPnUyAXKze+KNi9QiEz/IieyRnZfNztp7yvTFyBXOlVQP/JdYNZw2+GRQDg7grOR2ZjroqoOU2z0TNhy+qDHKSV8ZXOnxUF93w3DA51ADDQHB0IngL+v6N8KthdVZeZBe0d3EsUFS8ZJltNRUJ','encSecKey':'4801507e42c326dfc6b50539395a4fe417594f7cf122cf3d061d1447372ba3aa804541a8ae3b3811c081eb0f2b71827850af59af411a10a1795f7a16a5189d163bc9f67b3d1907f5e6fac652f7ef66e5a1f12d6949be851fcf4f39a0c2379580a040dc53b306d5c807bf313cc0e8f39bf7d35de691c497cda1d436b808549acc'} postdata=urllib.parse.urlencode(data).encode('utf8') #进行编码 request=urllib.request.Request(url,headers=header,data=postdata) reponse=urllib.request.urlopen(request).read().decode('utf8') json_dict=json.loads(reponse) #获取json hot_commit=json_dict['hotComments'] #获取json中的热门评论 num=0 fhandle=open('./song_comments','a') #写入文件 fhandle.write(hot_song_name+':'+'\n') for item in hot_commit: num+=1 fhandle.write(str(num)+'.'+item['content']+'\n') fhandle.write('\n==============================================\n\n') fhandle.close() hot_song_name,hot_song_id=get_all_hotSong() #获取热歌榜所有歌曲名称和id num=0 while num < len(hot_song_name): #保存所有热歌榜中的热评 print('正在抓取第%d首歌曲热评...'%(num+1)) get_hotComments(hot_song_name[num],hot_song_id[num]) print('第%d首歌曲热评抓取成功'%(num+1)) num+=1
訊息無誤~
總結
#以上是Python3實現爬蟲抓取網易雲音樂的熱門評論分析(圖)的詳細內容。更多資訊請關注PHP中文網其他相關文章!