這是一篇代碼文章,因為所有的文字將會以類似注釋的方式進行敘述,文字是對代碼的補充說明和解讀。
這是一篇避坑文章,尤其對於新人來說,這些坑你一定會遇到,希望你不會犯下跟我一樣的問題,從另一個角度來講,你們是幸運的。
本文在pycharm裡運行,python 版本3.6,在windows 10系統中運行,望周知。
好了,話不多說,開始碼代碼。
import numpy as npimport timeimport jsonfrom pandas.io.json import json_normalizeimport requestsimport pandas as pdimport jiebafrom PIL import Imageimport wordcloud
上述我應該不需要多說,就是導入需要的模塊,貌似有點多,但是也說明這裡的坑比較多,接著往下走。
pd.set_option('display.max_columns',None)
第一次利用pandas讀取文件時,尤其是欄位多到30幾個,行數多於幾萬行,這時會出現如下的景象:
發現列跟行都被省略了,這時你怎麼辦?你可能回答:我就蹭蹭,我不進去,不好意思,因為文件太大,你沒有辦法打開物理文件。那麼這個時候,一行代碼就用上了:
pd.set_option('display.max_columns',None)
用以顯示所有列,相應的還有display.max_rows 顯示所有行。
當你第一次見到該數據時,你需要對數據的記錄或者欄位進行一番簡單的了解,這個選項能讓你對數據有個初步概念。
當然了 pd.set_option裡有諸多的選項,在這裡不做深究,有興趣的可以課下公眾號搜索一下。
wangyimusic_comments = Nonefor i in range(100,1100,100): url = r'http://music.163.com/api/v1/resource/comments/R_SO_4_483671599?limit=100&offset={}'.format(str(i)) headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36'} response = requests.get(url,headers=headers)
1、這裡把網易雲評論的接口拿出來拓展一下
http://music.163.com/api/v1/resource/comments/R_SO_4_{111}?limit={222}&offset={333}
"111":這裡是指的歌曲的ID,如果你想下載任意一首歌曲的評論數據,你可以先去網易雲搜一下歌曲,對應的網址內就有這個歌曲ID。
"222":這裡是可以自己修改的,其實就是一頁顯示的評論條數,比如你可以是10,100,看你的心情,也得看後面的offset設置的簡單與否。
畢竟你要爬取多頁的數據,不能自己給自己找麻煩對吧。
"333":指的是從哪一條評論開始下一頁,比如100,意味著從第100條評論開始下一頁。如果你對資料庫的分頁limit比較熟悉,可能會更容易理解一些。
當然了,網易雲接口還有好多好玩兒的東西,具體請參照小五哥之前的微信公眾號文章《收藏這些API,獲取網易雲音樂數據超輕鬆》。
大家可以看看其他的網易雲音樂的接口介紹,很有意思,不過爬取的數量是有限制的,但是練練手總是足夠的。
2、關於requests庫
這是爬蟲的基本庫之一,用我們英語老師的話講:不要問原因,這是固定搭配,背下來即可。
requests.get(url,headers=headers)
主要是用來將網頁的原始碼給提取出來。
data = json.loads(response.text) comments = json_normalize(data['comments']) wangyimusic_comments=comments.append(wangyimusic_comments) print('抓取完第{}頁'.format(str(i//100))) time.sleep(np.random.randint(2, 7))
通過接口抓取數據我不知道有沒有速度的限制,但是我們在抓取正常網站數據時還是不要太過分。孔子曰:以和為貴,所以每次請求我就間隔了隨機的2~7秒的時間。
wangyimusic_comments.to_csv('hot_wangyimusict.csv',encoding='utf-8-sig',index=False)
關於json_normalize,這是我目前遇到的解析json為DataFrame格式最簡單的方式了(當然,也可能是我頭髮長見識短的原因)。
json_normalize(data['comments']) 直接將數據轉化為DataFrame格式了,這種方式我是一見鍾情。
畢竟簡潔是一種美,而且是一種大美。
關於寫入數據pd.to_csv 其實這裡沒有必要存入文件,因為我們可以直接保存在變量裡,直接在下面的語法中調用即可。
但是我想說的最重要的,幾乎每個人在爬取數據保存數據時都會遇到的報錯:
打開文件亂碼,這裡使用encoding='utf-8-sig',這樣就解決了寫入文件亂碼的異常,具體的原理為什麼encoding='utf-8'不行,而encoding='utf-8-sig'就可以了。
大家可以查閱CSDN文章《Python 讀取文件首行多了"\ufeff"字符串》,解釋的很通俗。我想說的次重要的,是index=False,如果不加這個參數,會導致DataFrame寫入文件帶有默認的index 1 2 3 ...
這個沒有意義的index,至少我是不想寫入文件保存下來的,因此直接去掉。
text = ''commts = wangyimusic_comments.contentfor commt in commts: text += ' '.join(jieba.lcut(commt))
曾經的jieba的安裝讓我頭疼,但是不知道為何,我直接在annaconda裡pip install jieba就直接成功了。
jieba.lcut是對每個評論進行分詞處理,通過join函數將分詞合成一個字符串。
background_image = np.array(Image.open(r'C:\Users\jiangms\Pictures\640.png'))
讀取圖片文件我一開始用的是,
import matplotlib.pyplot as pltplt.imread(img)
但是卻報了如下的錯:
UserWarning: mask image should be unsigned byte between 0 and 255
翻譯成人話:圖片可以展現,問題是沒有導入圖形的輪廓,而且出現了警告,意思是:掩碼圖像應為0到255之間的無符號字節,所以要將圖片轉為數組。
使用np.array(Image.open(img)),即可避免報錯信息,但是W H Y ??真的不了解 。
為什麼要用二值化圖片,原理並不清楚,之前學PS的時候也是在三原色,通道那兒糊塗著。
wc = wordcloud.WordCloud( font_path='C:/Windows/Fonts/SimHei.ttf', #設置字體,解決顯示口字型亂碼問題 mask=background_image, #圖片背景 # width=1200, #圖片寬度 # height=900, #圖片高度 max_words=1000, #最大詞數 max_font_size=150, # 最大字體大小 min_font_size=4, # 最小字體大小 scale=1.5 #)
需要說明的是如果參數mask存在的話,那麼高度和寬度參數將會失效,這個需要注意一下。
wc.generate(text)plt.imshow(wc)plt.show()#使用matplotlib進行顯示wc.to_file('wordcloud.jpg')#保存圖片
好了,文章到了這兒就結束了,有幾個注意點希望能給大家提醒,能給大家啟發。