大家好!我是霖hero
到點了上號網(wǎng)易云,很多人喜歡到夜深人靜的時候,在網(wǎng)易云聽音樂發(fā)表評論,正所謂:自古評論出人才,千古絕句隨口來,奈何本人沒文化,一句臥槽行天下!評論區(qū)集結(jié)各路大神,今天我們來爬取網(wǎng)易云音樂評論并做個詞云圖,看看大家都評論了啥。
爬取分析
首先我們打開網(wǎng)易云的某首歌曲,打開開發(fā)者工具,如下圖所示:

通過觀察可以發(fā)現(xiàn),網(wǎng)易云音樂評論存放在class=cmmts j-flag的div中,那么我們打開網(wǎng)頁的源代碼鍵盤按Ctrl+F看看網(wǎng)頁源代碼有沒有我們想要的音樂評論數(shù)據(jù),如下圖所示:

我們發(fā)現(xiàn)網(wǎng)頁源代碼沒有音樂評論數(shù)據(jù),我們推測網(wǎng)頁是經(jīng)過JavaScript處理數(shù)據(jù)后生成的結(jié)果,這些數(shù)據(jù)有可能是Ajax加載出來的,打開開發(fā)者工具,切換到Netword選項卡,重新刷新頁面并下滑,可以發(fā)現(xiàn)這里出現(xiàn)了很多的條目,看看有沒有和評論相關的Ajax請求,如下圖所示:

通過觀察可以發(fā)現(xiàn)音樂評論數(shù)據(jù)存放在get?csrf_token=請求中,但通過觀察發(fā)現(xiàn)get?csrf_token=請求中沒有任何規(guī)律,唯一不同的是Form Data中的params和encSecKey參數(shù)在每個get?csrf_token=都不一樣,如下圖所示:

通過這么大段人類看不懂的參數(shù),可以推測這些參數(shù)是通過特殊加密方式來進行加密的參數(shù),那么我們要破解這種特殊的加密方式,找到未加密過的參數(shù)并構(gòu)造該特殊加密的函數(shù)進行對未加密的參數(shù)進行加密,這樣就可以獲取到我們要的網(wǎng)頁請求的評論數(shù)據(jù)了。
很明顯,這種情況下讓初學爬蟲的小白來破解,幾乎不可能,那么怎么辦好呢。對于初學爬蟲的小白或者要求爬蟲效率不高的爬蟲項目來說,使用selenium自動化測試工具來進行爬取是個不錯的選擇。
正式爬取
在爬取之前,我們先來簡單了解一下selenium是什么。
selenium
selenium是一個自動化測試工具,對于網(wǎng)絡請求接口有很多加密參數(shù),其規(guī)律難找,很難使用分析Ajax、通過JavaScript渲染加載得到的網(wǎng)頁來說,selenium自動化測試工具是個不錯的選擇,我們可以通過selenium來模擬瀏覽器的運行方式,獲取當前瀏覽器呈現(xiàn)網(wǎng)頁的源代碼,做到所見即所爬。
在使用selenium前,我們要先安裝好selenium庫和配置好ChromeDriver驅(qū)動。
selenium庫的安裝如下
pip install selenium
ChromeDriver驅(qū)動的安裝:
首先查看自身的Chrome版本是多少,然后根據(jù)我們自身的版本號通過下載地址:http://npm.taobao.org/mirrors/chromedriver/來下載對應的ChromeDriver驅(qū)動。
例如:
Chrome版本為:92.0.4515.131(正式版本) (64 位)
則下載ChromeDriver驅(qū)動版本中的92.0.4515任意一個,如下圖所示:

下載完畢后,把解壓的chromedriver.exe文件拖到Python的Scripts目錄下,如下圖所示:

這樣ChromeDriver驅(qū)動的安裝與配置就完成了,接下來我們正式開始爬取網(wǎng)易云評論。
爬取網(wǎng)易云評論
獲取子Frame內(nèi)容
我們來爬取薛之謙的歌變廢為寶,打開開發(fā)者工具,觀察已經(jīng)通過JavaScript渲染出來的網(wǎng)頁代碼,如下圖所示:

通過觀察發(fā)現(xiàn),評論數(shù)據(jù)存放在class="n-cmt"的div中,而且網(wǎng)頁的代碼有兩個html標簽,由于selenium打開網(wǎng)頁后,默認是在父級Frame里面操作的,所以我們需要使用switch_to.frame()方法來切換Frame。具體代碼如下:
def get_saving_data():
browser = webdriver.Chrome()
browser.get('https://music.163.com/#/playlist?id=5033464627')
browser.switch_to.frame(0)
browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')
首先我們聲明瀏覽器對象,這里我們選擇了Chrome瀏覽器,接著通過瀏覽器對象發(fā)送get請求到網(wǎng)頁中,再使用switch_to.frame()方法切換到子Frame,這里我們傳入的參數(shù)是0,其意思是切換到第一個子Frame中,也就是上圖中的第二個html標簽,再使用execute_script()方法把網(wǎng)頁拉到最下面方便我們進行評論頁的跳轉(zhuǎn)。
這樣我們就成功獲取上圖中的第二個html標簽里面的內(nèi)容了,如下圖所示:

獲取評論
在上一步我們成功獲取到子Frame中的內(nèi)容,接下來將在內(nèi)容中提取我們想要的數(shù)據(jù),具體代碼如下所示:
for page in range(3):
comments_divs = browser.find_elements_by_css_selector('.itm')
for comments_div in comments_divs:
comments=comments_div.find_element_by_css_selector('.cnt.f-brk').text
comment=re.findall(':(.*)',comments)[0]
with open('text.txt',mode='a',encoding='utf-8')as f:
f.write(comment)
browser.find_element_by_css_selector('.zbtn.znxt').click()
time.sleep(1)
我們采用了CSS選擇器來進行數(shù)據(jù)的獲取,首先調(diào)用find_elements_by_css_selector()方法把所有class="itm"的div獲取出來,再通過for循環(huán)把每個class=".cnt.f-brk"的div文本獲取出來,然后使用正則表達式把獲取到的文本提取我們要的評論數(shù)據(jù),再使用click()方法點擊下一頁,這里我們還使用了sleep()方法,每點擊下一頁就休眠1秒,這樣可以讓JavaScript渲染完成再進行數(shù)據(jù)的獲取,否則會因為JavaScript還沒渲染完成,而無法獲取數(shù)據(jù)從而導致報錯,運行結(jié)果如下:

這里我們一共爬取了3頁。
保存評論
好了,在上一步我們已經(jīng)獲取到評論,接下來我們將評論以追加的形式寫入txt文本中,具體代碼如下:
with open('text.txt',mode='a',encoding='utf-8')as f:
f.write(comment)
結(jié)果展示

制作詞云
制作詞云我們需要jieba庫,wordcloud庫、imageio庫,其安裝方式如下:
pip install jieba
pip install wordcloud
pip install imageio
在前面的步驟中,我們已經(jīng)成功獲取到評論并把評論數(shù)據(jù)保存在txt文本中,接下來我們將開始制作詞云,具體代碼如下:
import jieba
import wordcloud
import imageio
img_read=imageio.imread('樹.jpg')
file_open=open('text.txt','r',encoding='utf-8')
txt=file_open.read()
Cloud=wordcloud.WordCloud(width=1000,height=1000,background_color='white',mask=img_read,scale=8,font_path='C:\Windows\Fonts\msyhbd.ttc',stopwords={'的','了','是'})
txtlist=jieba.lcut(txt)
string=' '.join(txtlist)
Cloud.generate(string)
Cloud.to_file('樹1.png')
首先我們導入jieba、wordcloud、imageio庫,再調(diào)用imageio.imread()方法來讀取詞云的背景圖,然后再調(diào)用wordcloud.WordCloud()方法,把詞云圖設置寬高為1000,背景色為白色,詞云圖背景為剛才讀取的圖片。
注意:當我們做的詞云有中文時,我們要把系統(tǒng)文字路徑傳入到wordcloud.WordCloud()方法中,這里我們還把“的,了,是”在詞云中屏蔽掉。
然后我們調(diào)用jieba.lcut()方法把text.txt文本中的文字進行切割,由于我們分割出來的文字是以列表的形式保存的,所以調(diào)用join()方法把列表轉(zhuǎn)換為字符
最后調(diào)用generate()方法生成詞云,調(diào)用to_file()方法保存詞云圖。
結(jié)果展示

好了,selenium爬取網(wǎng)易云評論并作詞云就到這里了,注意不到萬不得已,盡量不要使用selenium爬取,因為效率實在很低。