python爬蟲入門 實戰(三)---爬網易云音樂熱門評論


網易云音樂

本篇涉及知識:
1、request第三方庫的基本使用
2、json解析

本篇目標:
爬取指定一個歌單的所有歌曲的熱門評論

(注:本篇爬取不直接解析html文本,而是直接分析獲取評論的api,從而獲得相應的json返回。然后,解析json獲取所需信息。)

踩坑記錄:
1、換行符號“\”導致一些未知問題,慎用換行符號“\”


分析api

  • 我們首先用瀏覽器打開網易云音樂的網頁版,隨便進入一個歌單,點擊進入一首歌曲的頁面,可以看到下面有評論。接著F12進入開發者控制臺(審查元素)。
分析api

我們在搜索框里輸入comments即可找到對應的獲取評論的api的url,點擊它在右邊選擇Response就可以看到返回的json了。

那我們的思路就很清晰了,只需要分析這個api并模擬發送請求,獲取json進行解析就好了。右鍵復制這個url下來:

http://music.163.com/weapi/v1/resource/comments/R_SO_4_465920636?csrf_token=4377e7fd9c7eede75d669c60a951fbed

從瀏覽器的上的地址可以發現以上url里R_SO_4_后的數字就是歌曲的id,如下圖:



經測試,后面的csrf_tocken也可以用于其他歌曲。在開發者控制臺里,點擊headers就可以看到請求方式為post,請求頭里的表單數據有兩個加過密的參數(params和encSecKey)。但是不要緊,同樣經測試,這兩個參數也可以用于其他歌曲,直接copy就好。但只限于第一頁,其他頁碼就不一樣了,不過對于我們爬取熱門評論,第一頁就夠了。

發送請求獲取json

根據上個小節的分析,我們可以寫出以下代碼獲取到json:

import requests
import json

url='http://music.163.com/weapi/v1/resource/comments/R_SO_4_465920636?csrf_token=c0f6bfdcd0526ec0ba6c207051a08960'

param={'params':'wxLqdGgw16OHb6UwY/sW16VtLqAhGaDMeI2F4DaESDplHA+CPsscI4mgiKoVCPuWW8lcd9eY0YWR/iai0sJqs0NmtLubVCkGdpN\
TN3mLhevZpdZy/XM1+z7L18InFz5HbbRkq230i0aOco/3jVsMWcD3/tzzOCLkGuu5xdbo99aUjDxHwDSVfu4pz4spV2KonJ47Rt6vJhOorV7LfpIVmP/qe\
ZghfaXXuKO2chlqU54=',\
'encSecKey':'12d3a1e221cd845231abdc0c29040e9c74a47ee32eb332a1850b6e19ff1f30218eb9e2d6d9a72bd797f75\
fa115b769ad580fc51128cc9993e51276043ccbd9ca4e1f589a2ec479ab0323c973e7f7b1fe1a7cd0a02ababe2adecadd4ac93d09744be0deafd1eef\
0cfbc79903216b1b71a82f9698eea0f0dc594f1269b419393c0'}#這里每行末尾的‘\’是代碼過長用來換行的,慎用,換行多了易出現bug。

r=requests.post(url, param)

data=r.text#data得到的就是json
print data

運行查看輸出就可以知道是否成功獲取了json。這里requests的用法,可以參考requests快速上手

解析json進行輸出

我們可以從瀏覽器的開發者控制臺里把json復制到一個 在線json校驗格式化工具,這樣可以比較清晰地看到json的結構,利于我們解析。如圖:

json格式

這個json里有豐富的信息,包括評論總數、用戶名、熱評、點贊數等。清楚了json 的結構,很容易就可以解析得到想要的信息了。json解析需要引入json包,了解json解析可以參考 使用python解析json詳解。里面把json類型和python類型之間的對應關系講得很清楚了,只需要會用dict和list。解析代碼如下:

import requests
import json

url='http://music.163.com/weapi/v1/resource/comments/R_SO_4_465920636?csrf_token=c0f6bfdcd0526ec0ba6c207051a08960'

param={'params':'wxLqdGgw16OHb6UwY/sW16VtLqAhGaDMeI2F4DaESDplHA+CPsscI4mgiKoVCPuWW8lcd9eY0YWR/iai0sJqs0NmtLubVCkGdpN\
TN3mLhevZpdZy/XM1+z7L18InFz5HbbRkq230i0aOco/3jVsMWcD3/tzzOCLkGuu5xdbo99aUjDxHwDSVfu4pz4spV2KonJ47Rt6vJhOorV7LfpIVmP/qe\
ZghfaXXuKO2chlqU54=',\
'encSecKey':'12d3a1e221cd845231abdc0c29040e9c74a47ee32eb332a1850b6e19ff1f30218eb9e2d6d9a72bd797f75\
fa115b769ad580fc51128cc9993e51276043ccbd9ca4e1f589a2ec479ab0323c973e7f7b1fe1a7cd0a02ababe2adecadd4ac93d09744be0deafd1eef\
0cfbc79903216b1b71a82f9698eea0f0dc594f1269b419393c0'}#這里每行末尾的‘\’是代碼過長用來換行的

r=requests.post(url, param)

data=r.text
jsob=json.loads(data)#加載獲取的json數據,獲得json對象
hotComments=jsob['hotComments']
 
for i in range(len(hotComments)):
    user_nickname=hotComments[i]['user']['nickname']
    likedCount=hotComments[i]['likedCount']
    content=hotComments[i]['content']
     
    print u'評論'+str(i+1)+u' 用戶名:'+user_nickname+u" 喜歡:"+str(likedCount)
    print '------------------------------------------------------------------'
    print content
    print '------------------------------------------------------------------'
    print '\n'

輸出結果:

輸出結果

爬取一個歌單所有歌的熱門評論

以上已經展示了怎么爬取一首歌的熱門評論,接下來我們就可以進一步把一個歌單里所有歌的熱門評論都爬取出來。

思路就是,將這個歌單所有歌曲的id爬取出來,替換到之前的url中,然后進行同樣的輸出。

同樣的方法,我們發送歌單的url訪問請求,讀取response的返回內容看看情況。

url='http://music.163.com/playlist?id=700734626'
r=requests.get(url)
print r.text

輸出:

控制臺輸出

可以看到第一行的標簽textarea里有一個json,我們可以用xpath定位到這個標簽,獲取到這個json并進行解析。在此之前,可以向之前一樣先復制到在線校驗工具看看結構。

json結構

確實有我們需要的數據,接下來就可以進行解析了。

我們這里寫成面向對象的風格,完整代碼如下:

import requests
import json
from lxml import html
class CrawlMusic163:
   
    #獲取json解析出所有歌曲對象,返回歌曲的list
    def getSongs(self,id):#這里的id是歌單的id
        url='http://music.163.com/playlist?id='+str(id)
        r=requests.get(url)
         
        tree=html.fromstring(r.text)
        data_json=tree.xpath('//textarea[@style="display:none;"]')[0].text
          
        songs=json.loads(data_json)
        return songs
    
    #獲取每首歌的熱門評論的list
    def getHotComments(self,id):#這里的id是歌曲的id
        url='http://music.163.com/weapi/v1/resource/comments/R_SO_4_'+str(id)+'?csrf_token=c0f6bfdcd0526ec0ba6c207051a08960'
        
        param={'params':'wxLqdGgw16OHb6UwY/sW16VtLqAhGaDMeI2F4DaESDplHA+CPsscI4mgiKoVCPuWW8lcd9eY0YWR/iai0sJqs0NmtLubVCkG\
        dpNTN3mLhevZpdZy/XM1+z7L18InFz5HbbRkq230i0aOco/3jVsMWcD3/tzzOCLkGuu5xdbo99aUjDxHwDSVfu4pz4spV2KonJ47Rt6vJhOorV7LfpIVmP/qeZghfaXXuKO2chlqU54=',\
        'encSecKey':'12d3a1e221cd845231abdc0c29040e9c74a47ee32eb332a1850b6e19ff1f30218eb9e2d6d9a72bd797f75fa115b769ad580fc51128cc9993e51276043ccbd9ca4e1f589a2ec479ab0323c973e7f7b1fe1a7cd0a02ababe2adecadd4ac93d09744be0deafd1eef0cfbc79903216b1b71a82f9698eea0f0dc594f1269b419393c0'}
        r =requests.post(url,param)
        data=r.text
        jsob=json.loads(data)#加載獲取的json數據,獲得json對象
        hotComments=jsob['hotComments']
  
        return hotComments
 

crawl_music_163=CrawlMusic163()
songs=crawl_music_163.getSongs(700734626)#700734626是某個歌單的id,在網頁版進入歌單后可以在url末尾獲取
for song in songs:
    hotComments=crawl_music_163.getHotComments(song['id'])#按id獲取該歌曲的熱門評論list
    
    #輸出每首歌的歌手名字-歌名-熱門評論數
    print song['artists'][0]['name']+"-"+song['name']+u"-熱門評論:"+str(len(hotComments))
    print '########################################################################'
    
    #每首歌循環輸出所有熱門評論
    for i in range(len(hotComments)):
        user_nickname=hotComments[i]['user']['nickname']
        likedCount=hotComments[i]['likedCount']
        content=hotComments[i]['content']
            
        print u'評論'+str(i+1)+u' 用戶名:'+user_nickname+u" 喜歡:"+str(likedCount)
        print '------------------------------------------------------------------'
        print content
        print '------------------------------------------------------------------'
        print '\n'
    print '########################################################################'

輸出結果展示:

輸出結果示例

(注:這里遇到一個神坑,由于param太長,我用了幾個""符號在末尾進行換行,如上代碼那樣換了兩行沒有問題,可是只要我在encSecKey參數這一行進行換行,就會產生bug,死活獲取不到json文本。經過多次測試,確實就是""符號導致param沒能正確地傳入post導致獲取不到json文本。目前不清楚什么原因,所以,這個換行還是慎用。)

本文參考:

requests快速上手
使用python解析json詳解
Python 爬取百萬網易云音樂熱門評論

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,797評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,179評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,628評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,642評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,444評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,948評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,040評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,185評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,717評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,794評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,418評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,414評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,750評論 2 370

推薦閱讀更多精彩內容