抓取京東商城商品評論信息,并對這些評論信息進行分析和可視化。下面是要抓取的商品信息,一款女士文胸。這個商品共有紅色,黑色和膚色和磚紅四種顏色, 70B到90D共18個尺寸,以及1100+條購買評論。
京東商品評論信息是由JS動態加載的,所以直接抓取商品詳情頁的URL并不能獲得商品評論的信息。因此我們需要先找到存放商品評論信息的文件。這里我們使用Chrome瀏覽器里的開發者工具進行查找。
按快捷鍵F12,在彈出的開發者工具界面中選擇Network,設置為只查看JS文件。然后刷新頁面。頁面加載完成后向下滾動鼠標找到商品評價部分,等商品評價信息顯示出來后,在下面Network界面的左側篩選框中輸入productPageComments,這時下面的加載記錄中只有一條信息,這里包含的就是商品詳情頁的商品評論信息。點擊這條信息,在右側的Preview界面中可以看到其中包含了當前頁面中的評論信息復制這條信息,并把URL地址放在瀏覽器中打開,里面包含了當前頁的商品評論信息。這就是我們要抓取的URL地址'https://sclub.jd.com/comment/productPageComments.action?callback=fetchJSON_comment98vv90&productId=10001229490&score=0&sortType=5&page=0&pageSize=10&isShadowSku=0&fold=1'
仔細觀察這條URL地址可以發現,其中productId=10001229490是當前商品的商品ID。與商品詳情頁URL('https://item.jd.com/10001229490.html')中的ID一致。而page=0是頁碼。如果我們要獲取這個商品的所有評論,只需要更改page后面的數字即可。其中中‘callback=fetchJSON_comment98vv90’和‘isShadowSku=0&fold=1’,經測試,是可以刪除的,這樣可以簡化url,不至于看起來那么長。
在獲得了商品評論的真實地址以及URL地址的規律后,我們開始使用python抓取這件商品的1100+條評論信息,并對這些信息進行處理和分析。
開始前的準備工作
在開始抓取之前先要導入各種庫文件,這里我們分別介紹下需要導入的每個庫文件的名稱以及在數據抓取和分析中的作用。requests用于進行頁面抓取,time用于設置抓取過程中的Sleep時間,random用于生產隨機數,這里的作用是將抓取頁面的順序打亂,re用于在抓取后的頁面代碼中提取需要的信息,numpy用于常規的指標計算,pandas用于進行數據匯總和透視分析,matplotlib用于繪制各站圖表,jieba用于對評論內容進行分詞和關鍵詞提取。
將爬蟲偽裝成瀏覽器
導入完庫文件后,還不能直接進行抓取,因為這樣很容易被封。我們還需要對爬蟲進行偽裝,是爬蟲看起來更像是來自瀏覽器的訪問。這里主要工作是設置請求中的頭文件信息
頭文件信息很容易找到,在Chrome的開發者工具中選擇Network,刷新頁面后選擇Headers就可以看到本次訪問的頭文件信息,里面包含了一些瀏覽器的技術參數和引薦來源信息。將這些信息直接添加到代碼中就可以,這里我們將頭部信息保存在headers中。
1. ?#設置請求中頭文件的信息
headers={'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36'}
抓取商品評論信息
設置完請求的頭文件信息后,我們開始抓取京東商品評論的信息。前面分析URL的時候說過,URL中包含兩個重要的信息,一個是商品ID,另一個是頁碼。這里我們只抓取一個商品的評論信息,因此商品ID不需要更改。但這個商品的評論有1100+條,也就是有近100頁需要抓取,因此頁碼不是一個固定值,需要在0-100之間變化。這里我們將URL分成兩部分,通過隨機生成頁碼然后拼接URL的方式進行抓取。
2. ?#設置URL的第一部分
#設置URL的第二部分
url2 = '&pageSize=10&isShadowSku=0&fold=1'
3. ?#計算商品評論頁面總數
這里根據爬去的html長度判斷是否最后一頁,不具備合理性,也不具備可移植性,換成其它商品頁面就不可行了。(京東商品評論最多顯示100頁,不知道有沒有其它辦法可以爬取更多)
運行結果如下:
所以抓取范圍定位從0-69頁。
下面是具體的抓取過程,使用for循環每次從0-69的數中找一個生成頁碼編號,與兩部分的URL進行拼接。生成要抓取的URL地址并與前面設置好的頭文件信息發送請求獲取頁面信息。將獲取到的頁面信息進行匯總。每次請求間休息2秒鐘,避免過于頻繁的請求導致返回空值。
4. ?#拼接URL并亂序循環抓取頁面
在抓取的過程中輸入每一步抓取的頁面URL以及狀態。通過下面的截圖可以看到,在page參數后面的頁碼是隨機生成的并不連續。
抓取完頁面后,我們還需要對頁面進行編碼。完成編碼后就可以看到其中所包含的中文評論信息了。后面大部分苦逼的工作就是要對這些評論信息進行不斷提取和反復的清洗。
5#對抓取的頁面進行編碼
comment_content = str(comment_content, encoding="GBK")
這里建議將抓取完的數據存儲在本地,后續工作可以直接從本地打開文件進行清洗和分析工作。避免每次都要重新抓取數據。這里我們將數據保存在當前文件夾中的comment.txt文件中。
6#將編碼后的頁面輸出為txt文本存儲
f=open('comment.txt','w')
f.write(comment_content)
f.close()
讀取文件也比較簡單,直接open加read函數就可以完成了。
7#讀取存儲的txt文本文件
f=open('comment.txt','r')
html=f.read()
f.close()
提取信息并進行數據清洗
京東的商品評論中包含了很多有用的信息,我們需要將這些信息從頁面代碼中提取出來,整理成數據表以便進行后續的分析工作。這里應該就是整個過程中最苦逼的數據提取和清洗工作了。我們使用正則對每個字段進行提取。對于特殊的字段在通過替換等方式進行提取和清洗。
下面是提取的第一個字段userClient,也就是用戶發布評論時所使用的設備類型等字段
還有一些字段比較負責,無法通過正則一次提取出來,比如isMobile字段,有些值的后面還有大括號。這就需要進一步的提取和清洗工作。
1 #使用正則提取isMobile字段信息
使用for循環配合替換功能將字段中所有的}替換為空。替換完成后字段看起來干凈多了。
2 #使用正則提取productSize字段信息
productSize字段中包含了胸圍和杯罩兩類信息,為了獲得獨立的杯罩信息需要進行二次提取,將杯罩信息單獨保存出來。
3 #使用正則提取時間字段信息
日期和時間信息處于前20個字符,在二次提取中根據這個規律直接提起每個條目的前20個字符即可。將日期和時間單獨保存為creationTime。在上一步日期和時間的基礎上,我們再進一步提取出單獨的小時信息,方法與前面類似,提取日期時間中的第11和12個字符,就是小時的信息。提取完保存在hour字段以便后續的分析和匯總工作。
4 #對提取的評論信息進行去重
最后要提取的是評論內容信息,頁面代碼中包含圖片的評論信息是重復的,因此在使用正則提取完后還需要對評論信息進行去重。使用if進行判斷,排除掉所有包含圖片的評論信息,已達到評論去重的目的。
完成所有字段信息的提取和清洗后,將這些字段組合在一起生成京東商品評論數據匯總表。下面是創建數據表的代碼。數據表生成后還不能馬上使用,需要對字段進行格式設置,例如時間和日期字段和一些包含數值的字段。具體的字段和格式設置依據后續的分析過程和目的。這里我們將creationTime設置為時間格式,并設置為數據表的索引列。將days字段設置為數值格式。
5#將前面提取的各字段信息匯總為table數據表,以便后面分析
6#保存table數據表
table.to_csv('jd_table.csv')
數據分析及可視化
1. 分月評論數據變化趨勢
首先查看京東商品評論的時間變化趨勢情況,大部分用戶在購買商品后會在10天以內進行評論,因此我們可以近似的認為在一個月的時間維度中評論時間的變化趨勢代表了用戶購買商品的變化趨勢。
按月的維度對數據表進行匯總,并提取每個月的nickname的數量。下面是具體的代碼和分月數據
數據范圍從2015年11月到2017年4月。使用柱狀圖對分月數據進行可視化。從圖表中可以看到2016年6月是評論的高峰,也可以近似的認為這個時間段是用戶購買該商品的高峰(6月18日是京東店慶日)。排除2016年6月和不完整的11月數據,整齊趨勢中冬季評論量較低,夏季較高。這是由于該商品的季節屬性導致的,超薄胸罩更適合夏天佩戴(這個屬性我們是在用戶的評論中發現的,在京東的商品介紹中并不明顯,只在標題中以”薄杯”說明)。
2. PC和移動端使用情況
通過篩選將數據表分為使用移動設備和未使用移動設備兩個表格,再分別查看和對比評論變化趨勢。
從結果中可以看出使用移動設備進行評論的用戶在所有的時間段中都要明顯高于使用PC的用戶。
3. 24小時評論評論變化趨勢
按小時維度對評論數據進行匯總,查看用戶在24小時中的評論變化趨勢。這里需要說明的是24小時趨勢只能反映用戶登錄京東商城的趨勢,并不能近似推斷用戶購買商品的時間趨勢
從24小時評論趨勢圖來看,發布商品評論的趨勢與作息時間一致,并且每日的閑暇時間是發布評論的高峰。如早上的8點,中午的12點和晚上的22點,是一天24小時中的三個評論高峰點。
將24小時的評論數量分為移動設備和未使用移動設備,查看并對比這兩者的變化趨勢情況。
移動設備的評論數量在24小時中的各個時間段都要高于PC的評論數量,并且在晚間更加活躍,持續時間高于PC端。這里我們產生了一個疑問,在一天中的工作時間段中,大部分用戶都會在電腦旁,但為什么這些時間段里移動設備的評論數量也要高于PC端呢?這是否與胸罩這個產品的私密性有關聯。用戶不希望別人看到自己購買的商品或評論的內容,所以選擇使用移動設備進行評論?
4. 用戶客戶端分布情況
前面的分析中,我們看到使用移動設備進行評論的用戶要遠高于PC端的用戶,下面我們對用戶所使用的設備分布情況進行統計。首先在數據表中按用戶設備(userClient)對nickname字段進行計數匯總
從用戶客戶端分布情況來看,移動端的設備占大多數,其中使用移動端的用戶要高于Android用戶。由于微信購物和QQ購物單獨被分了出來,無法確定設備,因此單獨進行對比。使用微信購物渠道的用戶要高于QQ購物
5. 購買后評論天數分布
在購買后評論天數方面,我們將用戶發布評論與購買的時間間隔分為7組,分別為購買后1-5天內,5-10天內,10-15天內,15-20天內,20-25天內,25-30天內,以及大于30天。然后統計并對比用戶在不同時間區間內發布評論的數量情況。
從圖表中看出,購買后5天以內是用戶發布評論的高峰,也就我們之前推測評論時間趨勢近似于購買時間的依據。隨著時間的增加評論數量逐漸下降。
6. 胸罩顏色偏好分布
這款胸罩共分為三個顏色,紅色,膚色,黑色和磚紅色。我們按顏色對評論數據進行匯總,查看用戶對不同胸罩顏色的偏好情況
從不同顏色的評論數量上來看,大部分用戶購買的是磚紅色和紅色,購買黑色的用戶數量最少
8. D&E cup用戶城市分布情況
最后我們再看看下D杯罩和E杯罩用戶的城市分布情況,在數據表中并不是所有的評論都有城市信息。因此按城市統計出來的數據可能并不準確,僅供參考。
首先從數據表中篩選出cup值為D和E的數據,并保存在新的數據表中。
在新的數據表中按用戶所在城市(userProvince)進行匯總。查看不同城市D和E杯罩的數量。
將匯總結果繪制為圖表,從圖表來看,數量最多的為未知城市,排除未知城市,北京和廣東的數量遙遙領先,其次為四川和上海。
胸罩評論內容語義分析
文章最后我們對商品的評論內容進行語義分析,看看大家在評論中都在說些什么
好好先生購買比例
在人工查看了一些評論內容后,我們發現一些有意思的信息。有一部分評論是老公或男朋友發的,這說明一些好好先生會幫老婆或女友購買胸罩。那么這部分用戶的比例有多少呢?
我們把評論中包含有關鍵詞“老婆”和“女朋友”的評論單獨保存在出來
查看這些包含關鍵詞的評論內容,確實是老公和男朋友來購買胸罩并且發布的評論
經過計算,在這款胸罩產品的評論中,由老公或男朋友購買的比例僅為2.35%。
商品評論關鍵詞分析
回歸到商品評論分析,我們使用結巴分詞對所有胸罩的評論信息進行了分詞,并提取了權重最高的關鍵詞列表。
從高權重關鍵詞列表來看,用戶評論以正面信息為主,”不錯”,”舒服”,”喜歡”等主觀感受的正面評論權重較高
結語
由于抓取的數量少,結果僅供參考。當評論頁數較多式可以采用多線程爬蟲爬取商城評論,通過引用from multiprocessing.dummy importPool as ThreadPool,本代碼中,url_manager這個類在另外一個.py文件中,用于爬去所有頁面url,并返回url集合,這里我就不做展示了。還有一點是我使用的是python3.6版本,和python2.7在一些語法上的差別。
代碼如下:
參考
“藍鯨網站分析博客”