文/李依潼 王驥 任肖麗
(廣東海洋大學(xué)電子與信息工程學(xué)院 廣東省湛江市 524088)
電子商務(wù)的興起促進(jìn)了商業(yè)模式變革,物聯(lián)網(wǎng)、云計(jì)算的出現(xiàn)推動(dòng)信息爆發(fā)式增長(zhǎng),這是電商時(shí)代,亦是大數(shù)據(jù)時(shí)代,如何利用海量信息產(chǎn)生更多效益,成為商業(yè)競(jìng)爭(zhēng)的核心[1][2]。獲取有效數(shù)據(jù)是大數(shù)據(jù)研究的重點(diǎn),網(wǎng)絡(luò)爬蟲(chóng)技術(shù)是獲取互聯(lián)網(wǎng)海量數(shù)據(jù)的關(guān)鍵手段之一。
網(wǎng)絡(luò)爬蟲(chóng)是對(duì)不同網(wǎng)頁(yè)進(jìn)行下載和分析,經(jīng)過(guò)存儲(chǔ)、相關(guān)度計(jì)算、排序,再將關(guān)鍵詞展現(xiàn)到用戶(hù)面前[1]。本文以爬取京東購(gòu)物網(wǎng)站網(wǎng)頁(yè)數(shù)據(jù)為例,設(shè)計(jì)一個(gè)基于Scrapy框架的數(shù)據(jù)分析系統(tǒng)。在Python 3.7編程語(yǔ)言的Scrapy框架下搭建Web爬蟲(chóng),爬取京東網(wǎng)站搜索結(jié)果前兩頁(yè)商品信息、總體評(píng)價(jià)和每件商品前20頁(yè)評(píng)論,然后采用MongoDB實(shí)現(xiàn)持久化數(shù)據(jù)存儲(chǔ),再利用Python生態(tài)的Numpy、Pandas數(shù)據(jù)處理工具包對(duì)數(shù)據(jù)進(jìn)行清洗、轉(zhuǎn)換、分組、計(jì)算,最終基于Matplotlib實(shí)現(xiàn)分析結(jié)果可視化。通過(guò)反饋回的商品信息與解析結(jié)果,為商家制定個(gè)性化的營(yíng)銷(xiāo)策略提供依據(jù)。
爬蟲(chóng)也稱(chēng)網(wǎng)絡(luò)信息爬取技術(shù),通過(guò)網(wǎng)頁(yè)鏈接地址URL向服務(wù)器發(fā)送請(qǐng)求獲取網(wǎng)頁(yè)信息內(nèi)容。Web 爬蟲(chóng)
是一個(gè)自動(dòng)訪(fǎng)問(wèn)的互聯(lián)網(wǎng)程序,用來(lái)檢索Web頁(yè)面、提取必要信息、存入本地?cái)?shù)據(jù)庫(kù)[3]。
網(wǎng)絡(luò)爬蟲(chóng)基本工作流程如下[4]:
(1)選取精心挑選的種子URL;
(2)將種子URL放入待抓取URL隊(duì)列;
(3)從待抓取URL隊(duì)列取出待抓取URL,DNS解析后得到目標(biāo)主機(jī)Ip;
(4)下載URL對(duì)應(yīng)的網(wǎng)頁(yè)并存儲(chǔ)進(jìn)已下載的網(wǎng)頁(yè)庫(kù)中。同時(shí),將這些URL放進(jìn)已抓取URL隊(duì)列;
(5)分析已抓取URL隊(duì)列中的URL,獲取必要的數(shù)據(jù)存入數(shù)據(jù)庫(kù);
(6)分析其他URL,將URL放入待抓取URL隊(duì)列,進(jìn)入下一個(gè)循環(huán)。
Scrapy框架是使用Python開(kāi)發(fā)的一種快速、開(kāi)源的爬蟲(chóng)程序,可在運(yùn)行在Windows、Linux等多種主流操作平臺(tái),采用基于Twisted的下載器,提供了豐富的中間接口及較強(qiáng)的目錄約束,編寫(xiě)代碼清晰、可擴(kuò)展性好、可移植性強(qiáng)、可維護(hù)性高,用戶(hù)只需在Scrapy 框架基礎(chǔ)上定制開(kāi)發(fā)模塊即可實(shí)現(xiàn)高效的爬蟲(chóng)應(yīng)用[5][6]。Scrapy框架由調(diào)度器(Scheduler)、下載器(Downloader)、爬蟲(chóng)(Spider)、實(shí)體管道(Item Pipeline)、Scrapy引擎(Scrapy Engine)五大組件構(gòu)成。爬蟲(chóng)執(zhí)行流程如下[7][8]:
表1:工程目錄下文件和文件夾作用
圖1:系統(tǒng)整體架構(gòu)
(1)Spiders將待爬取網(wǎng)頁(yè)URL經(jīng)Scrapy Engine交給Scheduler;
(2)Scheduler處理后經(jīng)Scrapy Engine和Downloader Middleware交給Downloader;
(3)Downloader向Internet發(fā)送請(qǐng)求,接收Response,將Response經(jīng)Scrapy Engine和Scrapy Middelwares交給Spiders;
(4)Spiders處理提取Response后經(jīng)Scrapy Engine交給Pipeline保存;
(5)提取URL重復(fù)上述步驟,直到無(wú)URL請(qǐng)求或達(dá)到停止條件。
數(shù)據(jù)清洗和處理采用Numpy和Pandas兩個(gè)庫(kù),NumPy是Python科學(xué)計(jì)算的基礎(chǔ)包,作為算法和庫(kù)之間傳遞數(shù)據(jù)的容器,它提供了快速數(shù)組處理能力;Pandas能夠進(jìn)行復(fù)雜精細(xì)索引,它提供了大量處理結(jié)構(gòu)化數(shù)據(jù)的函數(shù),更加便捷地完成重塑、切塊、聚合、選取數(shù)據(jù)子集等操作[9][10]。
數(shù)據(jù)可視化使用Matplotlib圖形庫(kù),它是用Python 語(yǔ)言編寫(xiě)的二維圖形庫(kù),充分利用了Python簡(jiǎn)潔優(yōu)美和面向?qū)ο蟮奶攸c(diǎn),便于繪出直方圖、功率譜、條形圖、散點(diǎn)圖等,Matplotlib提供的相關(guān)API,使得圖表可以嵌入Tkinter畫(huà)布中。Matplotlib繪制的圖形使用Python標(biāo)準(zhǔn)Tk GUI工具包接口分析數(shù)據(jù),再利用Tkinter庫(kù)編寫(xiě)程序的GUI,即可實(shí)現(xiàn)數(shù)據(jù)的可視化呈現(xiàn)。
爬蟲(chóng)獲取的數(shù)據(jù)不包含復(fù)雜關(guān)系,且數(shù)據(jù)模型經(jīng)常變動(dòng),因此相較于傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù),本文選取非關(guān)聯(lián)數(shù)據(jù)庫(kù)MongoDB。MongoDB是由C++編寫(xiě)的基于分布式文件存儲(chǔ)的數(shù)據(jù)庫(kù),支持?jǐn)?shù)據(jù)結(jié)構(gòu)松散,查詢(xún)語(yǔ)言功能強(qiáng)大,可以存儲(chǔ)復(fù)雜的數(shù)據(jù)類(lèi)型。同時(shí),MongoDB使用集合的概念存儲(chǔ)數(shù)據(jù),不會(huì)過(guò)多檢測(cè)約束關(guān)系及數(shù)據(jù)合法性,存取效率高,對(duì)于Web中IO密集型的數(shù)據(jù)源優(yōu)勢(shì)巨大。
系統(tǒng)主要包括數(shù)據(jù)來(lái)源的爬蟲(chóng)模塊及數(shù)據(jù)處理與可視化模塊。首先啟動(dòng)Scrapy爬蟲(chóng)對(duì)目標(biāo)網(wǎng)站進(jìn)行爬取,Piplines接收數(shù)據(jù)并存儲(chǔ)在MongoDB數(shù)據(jù)庫(kù)中。啟動(dòng)數(shù)據(jù)處理和可視化GUI程序,啟動(dòng)后彈出窗口包含三個(gè)頁(yè)面,分別是商品總體數(shù)據(jù)、用戶(hù)數(shù)據(jù)和商品列表頁(yè)。商品總體數(shù)據(jù)展示品牌占比、不同價(jià)位的評(píng)論分布情況、同類(lèi)型商品描述詞頻;用戶(hù)數(shù)據(jù)展示用戶(hù)身份、用戶(hù)下單設(shè)備等;列表頁(yè)展示爬取到的商品分析數(shù)據(jù),雙擊會(huì)彈出好評(píng)、中評(píng)、差評(píng)占比,不同時(shí)間段的評(píng)論分布,用戶(hù)情感詞云,評(píng)論詞頻。系統(tǒng)總體架構(gòu)如圖1所示。
3.2.1 項(xiàng)目初始化
選取京東網(wǎng)站作為爬取目標(biāo),用scrapy startproject
JD_Spider生成爬蟲(chóng)項(xiàng)目,項(xiàng)目根目錄為JD_Spider。在根目錄下創(chuàng)建表1所示的文件或文件夾。
3.2.2 數(shù)據(jù)實(shí)體模型
Scrapy需建立實(shí)體模型來(lái)描述爬取數(shù)據(jù)[11]。設(shè)計(jì)的實(shí)體模型包括商品信息模型、店鋪信息模型及評(píng)論信息模型。其中商品信息模型描述商品名稱(chēng)、品牌、價(jià)格; 店鋪信息模型描述店鋪名、店鋪ID; 評(píng)論信息模型描述評(píng)論內(nèi)容、評(píng)論時(shí)間。MongoDB允許不同集合間出現(xiàn)關(guān)聯(lián)關(guān)系,使得數(shù)據(jù)庫(kù)存儲(chǔ)結(jié)構(gòu)清晰,模型關(guān)系如圖2所示。
3.2.3 爬取策略制定
京東評(píng)論數(shù)量和商品數(shù)量巨大,本文只爬取部分?jǐn)?shù)據(jù),爬取最大頁(yè)數(shù)通過(guò)settings.py設(shè)置,每次爬取完一個(gè)頁(yè)面page+1。爬取商品搜索結(jié)果時(shí),提取訪(fǎng)問(wèn)詳情頁(yè)URL,使用Ajax技術(shù)加載商品評(píng)論及整體評(píng)價(jià),讓爬蟲(chóng)向?qū)Ψ椒?wù)器發(fā)送請(qǐng)求,得到數(shù)據(jù)反饋后再提取數(shù)據(jù)。
3.2.4 反爬蟲(chóng)處理機(jī)制
提高爬取成功率需讓爬蟲(chóng)模擬瀏覽器行為。瀏覽器每次向服務(wù)器發(fā)送請(qǐng)求時(shí)會(huì)攜帶User-Agent頭部信息,在middlewares.py文件的中間件內(nèi)部定義一個(gè)包含常用瀏覽器信息的數(shù)組:
圖2:爬蟲(chóng)數(shù)據(jù)模型關(guān)系
圖3:爬蟲(chóng)執(zhí)行流程
隨后在中間件鉤子函數(shù)process_request中,使用隨機(jī)取值方法取出一個(gè)列表項(xiàng),通過(guò)request對(duì)象設(shè)置請(qǐng)求頭,最后在settings.py設(shè)置啟用該中間件,即可使爬蟲(chóng)模擬瀏覽器。當(dāng)訪(fǎng)問(wèn)商品詳情頁(yè)時(shí),服務(wù)器會(huì)檢測(cè)Referrer請(qǐng)求頭,該請(qǐng)求頭值為跳轉(zhuǎn)詳情頁(yè)之前的上一頁(yè)面。當(dāng)請(qǐng)求詳情URL時(shí),在Scrapy的Request中設(shè)置Referer為當(dāng)前URL,即可以獲取商品詳情頁(yè)的數(shù)據(jù)。
為防止爬取某頁(yè)面時(shí)突然中止,將每個(gè)商品id保存到數(shù)組中,當(dāng)頁(yè)面爬取完成時(shí)調(diào)用對(duì)應(yīng)URL,并將id作為參數(shù)向服務(wù)器發(fā)送請(qǐng)求加載剩下的數(shù)據(jù)進(jìn)行解析,再翻頁(yè)處理、爬取下一頁(yè)。爬蟲(chóng)執(zhí)行流程如圖3所示。
表2:目錄下文件和文件夾作用
圖4:界面架構(gòu)
圖5:數(shù)據(jù)處理及可視化模塊運(yùn)行流程
3.3.1 項(xiàng)目初始化
創(chuàng)建名為Analysis目錄文件夾,在該目錄下新建如表2所示的文件或文件夾。
3.3.2 界面設(shè)計(jì)
使用Tkinter開(kāi)發(fā)界面,界面窗口包括商品整體數(shù)據(jù)、用戶(hù)數(shù)據(jù)、商品列表三部分,默認(rèn)頁(yè)是商品數(shù)據(jù)頁(yè),通過(guò)UI頂部按鈕切換。在UI主類(lèi)Application中定義了一個(gè)屬性frames,數(shù)據(jù)結(jié)構(gòu)為字典,然后將三個(gè)頁(yè)面存儲(chǔ)進(jìn)字典中并讓其重疊,僅最上面可見(jiàn),通過(guò)改變各頁(yè)面的z軸順序切換頁(yè)面。圖表的顯示由Tkinter畫(huà)布和Matplotlib相結(jié)合繪制。界面架構(gòu)如圖4所示。
3.3.3 商品整體數(shù)據(jù)
(1)廠商占比。讀取數(shù)據(jù)庫(kù)中Products集合,由Pandas將其轉(zhuǎn)換為DataFrame,調(diào)用grouby函數(shù)按brand分組,然后對(duì)commentCount列調(diào)用sum函數(shù)求和,統(tǒng)計(jì)出各品牌評(píng)論總數(shù),再處理DataFrame提取品牌(brand)和評(píng)論數(shù)(commentCount)并作為元組返回,最后通過(guò)Matplotlib在Tkinter中繪制。
(2)商品描述詞頻。統(tǒng)計(jì)前十的描述詞,Pandas讀取商品信息后獲取description信息并轉(zhuǎn)換為列表數(shù)據(jù),然后使用Jieba中文分詞工具對(duì)商品描述進(jìn)行精確分詞,再用Pandas將其轉(zhuǎn)換為DataFrame,調(diào)用agg并結(jié)合Numpy的size統(tǒng)計(jì)相關(guān)詞頻并排序,取前10結(jié)果轉(zhuǎn)換為字典返回,通過(guò)Matplotlib在Tkinter中繪制。
(3)商品評(píng)價(jià)數(shù)量隨價(jià)格變動(dòng)。Pandas讀取商品數(shù)據(jù),將price字段換為數(shù)值類(lèi)型,分別統(tǒng)計(jì)0-1000、1000-2000、2000-3000、3000-5000、5000-6000、6000以上的評(píng)論數(shù)并返回?cái)?shù)據(jù),在通過(guò)Matplotlib在Tkinter中繪制。
3.3.4 用戶(hù)數(shù)據(jù)
(1)用戶(hù)身份。Pandas讀取所有評(píng)論,groupby函數(shù)按userLevelName字段分組,調(diào)用size求和統(tǒng)計(jì)并返回?cái)?shù)據(jù),通過(guò)Matplotlib在Tkinter中繪制。
(2)下單設(shè)備構(gòu)成。Pandas讀取評(píng)論后按userClient
Show字段分組,占比小于1%的字段相加,歸為Others并返回?cái)?shù)據(jù),通過(guò)Matplotlib在Tkinter中繪制。
3.3.5 商品列表
(1)商品列表顯示。Tkinter的treeview組件從數(shù)據(jù)庫(kù)讀取商品數(shù)據(jù)顯示在列表中,列表添加雙擊事件,事件觸發(fā)時(shí)顯示對(duì)該商品的數(shù)據(jù)可視化。
(2)好、中、差評(píng)占比。從數(shù)據(jù)庫(kù)中讀取數(shù)據(jù)并返回,通過(guò)Matplotlib在Tkinter中繪制。
(3)評(píng)論數(shù)量隨時(shí)間變動(dòng)。Pandas讀取數(shù)據(jù)后轉(zhuǎn)換為datetime對(duì)象,再轉(zhuǎn)化成year-month形式,按時(shí)間分組排序返回?cái)?shù)據(jù),通過(guò)Matplotlib在Tkinter中繪制。
(4)評(píng)論詞頻和詞云。Pandas讀取評(píng)論內(nèi)容后轉(zhuǎn)化為list,Jieba對(duì)評(píng)論精確分詞,排除停用詞并統(tǒng)計(jì)詞頻返回,在main.py文件中調(diào)用函數(shù)得到詞頻,選出排名前十的詞繪制詞頻統(tǒng)計(jì)表。詞云使用WordCloud讀取詞頻,將詞云顯示出來(lái)。
數(shù)據(jù)處理和可視化模塊工作流程如圖5所示。
settings.py設(shè)置關(guān)鍵詞為“手機(jī)”,最大商品頁(yè)數(shù)為2,最大評(píng)論頁(yè)數(shù)為20。排除預(yù)約階段的產(chǎn)品,啟動(dòng)爬蟲(chóng)等待一段時(shí)間,爬蟲(chóng)運(yùn)行完畢打開(kāi)MongoDB可視化工具,連接數(shù)據(jù)庫(kù)找到爬蟲(chóng)保存的數(shù)據(jù)。抓取到的商品數(shù)量為46個(gè),評(píng)論數(shù)量為9800條,店鋪數(shù)量為18家。該結(jié)果對(duì)于設(shè)置最大頁(yè)數(shù)2頁(yè)、最大評(píng)論頁(yè)數(shù)20頁(yè)、排除部分預(yù)約商品而言完全符合預(yù)期。
4.2.1 商品整體數(shù)據(jù)分析
爬蟲(chóng)執(zhí)行完成后,數(shù)據(jù)庫(kù)已存在必要數(shù)據(jù),設(shè)置好待連接的數(shù)據(jù)庫(kù),啟動(dòng)程序顯示商品數(shù)據(jù)的可視化分析。圖6分別為前兩頁(yè)廠商評(píng)論數(shù)占比和商品描述詞頻。分析可見(jiàn),Apple、華為、小米占據(jù)了銷(xiāo)售前三甲,手機(jī)網(wǎng)絡(luò)、機(jī)身、拍照功能、內(nèi)存和配置是廠商宣傳的賣(mài)點(diǎn)。
圖6:廠商評(píng)論占比及商品描述詞頻
4.2.2 用戶(hù)數(shù)據(jù)分析
抓取的9800條評(píng)論中,數(shù)量最大的是PLUS會(huì)員。PLUS會(huì)員是京東推出的會(huì)員服務(wù),這類(lèi)用戶(hù)注重購(gòu)物體驗(yàn),常購(gòu)物且更樂(lè)于發(fā)表評(píng)論。評(píng)論用戶(hù)身份組成如圖7所示。
4.2.3 單一商品數(shù)據(jù)分析
切換到商品列表頁(yè),買(mǎi)家評(píng)論和評(píng)論趨勢(shì)是評(píng)論數(shù)據(jù)中的重要信息。以華為P30為例,雙擊該記錄,彈出該商品的數(shù)據(jù)可視化圖表如圖8所示。分析可見(jiàn),用戶(hù)非常認(rèn)可這款產(chǎn)品,好評(píng)率達(dá)98.1%,差評(píng)1.2%;評(píng)論數(shù)在2019年8-10月最高,一定程度反映商品發(fā)布幾個(gè)月后打折促銷(xiāo),銷(xiāo)量較高。
商品詞頻和詞云反映用戶(hù)體驗(yàn),如圖9所示。分析可見(jiàn),用戶(hù)體驗(yàn)主要體現(xiàn)在系統(tǒng)流暢度、外觀、信號(hào)方面。
圖7:評(píng)論用戶(hù)身份組成
圖8:評(píng)論占比及高品評(píng)論變化趨勢(shì)
圖9:評(píng)論詞頻和用戶(hù)印象詞云
數(shù)據(jù)是企業(yè)無(wú)形的競(jìng)爭(zhēng)力,大數(shù)據(jù)處理已彰顯不可估量的價(jià)值。本文基于爬蟲(chóng)技術(shù),以京東網(wǎng)站的手機(jī)數(shù)據(jù)作為數(shù)據(jù)源,采用Python語(yǔ)言下Scrapy框架開(kāi)發(fā)爬蟲(chóng)程序,爬取數(shù)據(jù)存入非關(guān)聯(lián)數(shù)據(jù)庫(kù)MongoDB,通過(guò)實(shí)例演示數(shù)據(jù)挖掘并將數(shù)據(jù)以直觀、易讀的方式可視化呈現(xiàn)。一方面可以讓消費(fèi)者直觀享受消費(fèi)過(guò)程,另一方面幫助銷(xiāo)售商提煉用戶(hù)信息、把控用戶(hù)喜好、培養(yǎng)用戶(hù)習(xí)慣,實(shí)現(xiàn)精準(zhǔn)營(yíng)銷(xiāo)。