黃蓉 毛紅霞
摘 ?要:文章基于Python程序設(shè)計(jì)實(shí)現(xiàn)了對(duì)豆瓣網(wǎng)站上《小時(shí)代》系列電影影評(píng)、劇照、歌曲的爬取,并針對(duì)爬取的影評(píng)做出相應(yīng)的數(shù)據(jù)清洗以及數(shù)據(jù)可視化的展示。通過爬取豆瓣網(wǎng)站電影影評(píng)及相關(guān)劇照,分析大眾對(duì)電影的態(tài)度以及電影本身的特色,并對(duì)影評(píng)數(shù)據(jù)進(jìn)行清洗,進(jìn)而通過數(shù)據(jù)可視化的具體形式直觀的展現(xiàn)觀眾的評(píng)價(jià),從而解釋某種關(guān)于影視作品的現(xiàn)象。
關(guān)鍵詞:網(wǎng)絡(luò)爬蟲;數(shù)據(jù)采集;影評(píng);可視化
中圖分類號(hào):TP393.09 ? ? 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):2096-4706(2020)23-0004-04
Data Collection and Visual Analysis of a Series of Films Based on Douban.com
HUANG Rong,MAO Hongxia
(School of Computer and Software,Jincheng College of Sichuan University,Chengdu ?611731,China)
Abstract:Based on Python program design,this paper realized crawling of film reviews,stills and songs of Tiny Times series on Douban.com,and made corresponding data cleaning and data visual display for crawling of film reviews. Through crawling the film reviews and relevant stills on Douban.com,analyze the publics attitude towards the film and the characteristics of the film itself,and clean the film review data,and then intuitively show the audiences comments through the specific form of data visualization,so as to explain a certain phenomenon about film and television works.
Keywords:web crawler;data collection;film review;visualization
0 ?引 ?言
目前國(guó)內(nèi)影視行業(yè)存在一種“爛片高票房”的現(xiàn)象,而《小時(shí)代》這個(gè)系列電影就是“爛片高票房”的一個(gè)典型例子,從《小時(shí)代》上映后就遭到很多著名的影評(píng)人的批評(píng),大家一致認(rèn)為這部影片質(zhì)量不高,但仍有大部分人選擇花錢、花時(shí)間去觀看。為更好的解釋這一現(xiàn)象,筆者基于學(xué)校專業(yè)課程學(xué)習(xí)的Python內(nèi)容與網(wǎng)絡(luò)爬蟲內(nèi)容,選擇利用爬蟲技術(shù)對(duì)電影影評(píng)、劇照以及歌曲進(jìn)行爬取,對(duì)電影本身及觀眾感受逐一分析,并通過可視化將數(shù)據(jù)展示出來。
1 ?數(shù)據(jù)采集
1.1 ?網(wǎng)絡(luò)爬蟲技術(shù)
網(wǎng)絡(luò)爬蟲又通常被人們稱為網(wǎng)頁(yè)蜘蛛,它是用特定規(guī)則去爬取靜態(tài)或者動(dòng)態(tài)網(wǎng)頁(yè)中所需要的數(shù)據(jù)或內(nèi)容的一種方法[1],換而言之網(wǎng)絡(luò)爬蟲的本質(zhì)就是自動(dòng)抓取網(wǎng)頁(yè)信息的一段代碼。爬取數(shù)據(jù)的基本過程可以分為四步,分別是:發(fā)送一個(gè)requests字樣請(qǐng)求,通過HTTP庫(kù)向目標(biāo)服務(wù)器站點(diǎn)發(fā)送請(qǐng)求,等待對(duì)方服務(wù)器的響應(yīng);獲取響應(yīng)內(nèi)容,如果服務(wù)器能做出正常響應(yīng),那么就會(huì)得到一個(gè)response回應(yīng),里面所包含的內(nèi)容便是希望得到的網(wǎng)頁(yè)頁(yè)面內(nèi)容;解析網(wǎng)頁(yè)內(nèi)容,由于得到的內(nèi)容可能是HTML代碼,一般需要用到正則表達(dá)式或者XPath等等進(jìn)行網(wǎng)頁(yè)解析;保存需要的數(shù)據(jù),可以將內(nèi)容存為文本、表格,也可以保存在數(shù)據(jù)庫(kù)里。本文所用方法是基于Python語(yǔ)言進(jìn)行的網(wǎng)頁(yè)數(shù)據(jù)爬取,利用Python本身提供的眾多數(shù)據(jù)庫(kù),高效、精準(zhǔn)的進(jìn)行網(wǎng)頁(yè)抓取、網(wǎng)頁(yè)解析、數(shù)據(jù)存儲(chǔ)等操作[2]。
1.2 ?應(yīng)對(duì)反爬策略
爬蟲的速度是遠(yuǎn)遠(yuǎn)高于人類的速度的,所以在使用爬蟲的時(shí)候會(huì)占用相當(dāng)一大部分服務(wù)器的帶寬,這就增大了服務(wù)器的負(fù)載,甚至在大量用戶訪問的情況下會(huì)造成網(wǎng)絡(luò)擁堵,并且如果網(wǎng)絡(luò)爬蟲被濫用,會(huì)出現(xiàn)網(wǎng)絡(luò)上數(shù)據(jù)內(nèi)容雷同甚至一模一樣的情況,使得原創(chuàng)作品得不到保護(hù),于是,很多網(wǎng)頁(yè)會(huì)設(shè)置反爬蟲機(jī)制,來打破這樣的局面。那么當(dāng)用戶真正需要爬取數(shù)據(jù)的時(shí)候,就必須對(duì)爬蟲進(jìn)行偽裝。以下便是本項(xiàng)目應(yīng)對(duì)反爬的策略:
(1)偽裝用戶代理,將請(qǐng)求頭部User-Agent字段改為瀏覽器的User-Agent后再發(fā)送請(qǐng)求User-Agent[3]。
(2)設(shè)定休眠時(shí)間,人為瀏覽網(wǎng)頁(yè)總是會(huì)停頓幾秒,為了使爬蟲與人類相似,一般在爬取的時(shí)候會(huì)將爬蟲設(shè)置特定的休眠時(shí)間從而模擬人為登錄狀態(tài)[4],由此會(huì)使用time庫(kù)中的sleep函數(shù),在Selenium登入時(shí)模擬用戶的點(diǎn)擊延時(shí)行為。
(3)使用代理IP訪問網(wǎng)站,豆瓣網(wǎng)頁(yè)在爬蟲頻繁登陸后會(huì)封禁該IP一段時(shí)間,而利用代理IP,使得同一IP訪問豆瓣服務(wù)器的頻率相對(duì)減小,服務(wù)器難以檢測(cè)[5],避免IP被封。
(4)偽裝Cookie,一般情況下,網(wǎng)站會(huì)通過檢驗(yàn)請(qǐng)求信息中是否存在Cookie,以及利用Cookie的值來判斷該請(qǐng)求到底是真實(shí)用戶還是爬蟲[6],所以需要在用戶某次登錄時(shí)獲取Cookie,將其加入到請(qǐng)求頭中,達(dá)到模仿用戶登錄獲取數(shù)據(jù)的效果。
1.3 ?模擬登錄豆瓣網(wǎng)
模擬登錄網(wǎng)頁(yè)通常有兩種方式,一種是requests請(qǐng)求,一種是Selenium模擬瀏覽器自動(dòng)登錄,本項(xiàng)目選擇第二種方式登錄豆瓣網(wǎng)。第一步,找到登錄界面的網(wǎng)址,利用driver= webdriver.Chrome()啟動(dòng)瀏覽器,將找到的網(wǎng)址放入driver.get()方法中;第二步,利用driver.find_element_by_xpath()方法定位到密碼登錄的位置:用f12打開開發(fā)工具,利用鼠標(biāo)點(diǎn)擊可以找到其位置,代碼表示為://*[@id="account"]/div[2]/div[2]/ div/div[1]/ul[1]/li[2];第三步,依次定位賬號(hào)密碼框,利用send_keys()輸入內(nèi)容,第四步,獲取登錄按鈕的位置,click()點(diǎn)擊登錄即完成模擬登錄。
主要代碼為:
#點(diǎn)擊密碼登陸,豆瓣登陸框默認(rèn)手機(jī)號(hào)登陸
password_login=driver.find_element_by_xpath('//*[@id="account"]/div[2]/div[2]/div/div[1]/ul[1]/li[2]')
password_login.click()
#找到賬號(hào)框
username=driver.find_element_by_css_selector('#username')
username.click()
username.clear()
username.send_keys('***')
time.sleep(2)
#找到密碼框
password=driver.find_element_by_css_selector('#password')
password.click()
password.clear()
password.send_keys('***')
time.sleep(2)
#找到登錄框
submit=driver.find_element_by_xpath('//*[@id="account"]/div[2]/div[2]/div/div[2]/div[1]/div[4]/a')
print('準(zhǔn)備登陸...')
submit.click()
time.sleep(5)
1.4 ?影評(píng)爬取
在影評(píng)爬取之前,需要找到電影的鏈接,因?yàn)椤缎r(shí)代》系列電影有四部,所以考慮利用Selenium定位獲取四部電影的名字以及鏈接,在利用Selenium自動(dòng)搜索電影名稱的時(shí)候,發(fā)現(xiàn)當(dāng)跳出新窗口時(shí),driver定位的還是上一個(gè)窗口展現(xiàn)的頁(yè)面,導(dǎo)致不能正確的輸入想要的字段使得結(jié)果報(bào)錯(cuò)或者元素定位錯(cuò)誤,所以利用driver.window_handles[1]切換頁(yè)面句柄,讓driver自動(dòng)定位到新的窗口上,最后將名字和鏈接存放在字典里一一對(duì)應(yīng)。每部電影需要爬取前500條數(shù)據(jù),每頁(yè)有20條數(shù)據(jù),則需要爬取25頁(yè),這里涉及到翻頁(yè)處理問題,通過網(wǎng)頁(yè)鏈接的規(guī)律可知,在這25頁(yè)中,只有start的值在發(fā)生變化,則可以用循環(huán)語(yǔ)句來代替人工翻頁(yè),代碼為:link=v+'comments?start={}&limit=20&status=P&sort=new_score'.format(page*20),這里的page表示0到24,v
代表前面電影的鏈接,然后用xpath提取所需要的內(nèi)容,具體代碼為:
l = s.get(url=link, headers=headers,proxies=proxies)
html = l.content.decode('utf-8')
html = etree.HTML(html, parser=etree.HTMLParser (encoding='utf-8'))
#名字
host = html.xpath('//span[@class="comment-info"]/a/text()')
# 評(píng)分
gra = html.xpath('//span[@class="comment-info"]/span[2]/@title')
#內(nèi)容
for c in range(1, 21):
con=html.xpath('//*[@id="comments"]/div[{}]/div[2]/p/span/text()'.format(c))
1.5 ?劇照爬取
在爬取劇照時(shí),同樣涉及到翻頁(yè)問題,網(wǎng)頁(yè)鏈接的規(guī)律與影評(píng)一致,都是只有start參數(shù)改變,可將翻頁(yè)處理寫成:url_photo=v+photos?type=S&start={}&sortby=like&size=a&subtype=a'.format(page * 30),主要代碼為:
# 解析網(wǎng)頁(yè)
print("開始爬取{}頁(yè)".format(page + 1))
response = requests.get(url_photo, headers=headers,proxies=proxies)
if response.status_code == 200:
soup = BeautifulSoup(response.text, "lxml")
imgTags = soup.find_all("div", attrs={"class": "cover"})
# 獲取圖片鏈接以及名字
for imgTag in imgTags:
src = imgTag.img.get("src")
name = imgTag.parent.get("data-id") + movie_name[i]
# print(src)
resp = requests.get(src, headers=headers,proxies=proxies)
1.6 ?音樂爬取
音樂與影評(píng)、劇照所不同的是,四部電影音樂總和較少,一共15條,所以不涉及翻頁(yè)處理,直接在音樂界面獲取即可,代碼為:
def get_message(response):
html=response.content.decode('utf-8')
html=etree.HTML(html,parser=etree.HTMLParser (encoding='utf-8')) res_url=html.xpath(r'//*[@id="content"]/div/div[1]/div[3]/div[2]
//a/@href')#網(wǎng)址 res_song=html.xpath(r'//*[@id="content"]/div/div[1]/div[3]/div[2]//a/text()')#歌名
res_text=html.xpath(r'//*[@id="content"]/div/div[1]/div[3]/div[2]//p/text()')#歌曲簡(jiǎn)介
return res_song,res_text,res_url
2 ?數(shù)據(jù)清洗
在數(shù)據(jù)收集時(shí)或者收集之后需要對(duì)其進(jìn)行清洗,為后續(xù)數(shù)據(jù)可視化做準(zhǔn)備,對(duì)此,本項(xiàng)目采用的數(shù)據(jù)清洗步驟為:
(1)在爬取影評(píng)時(shí),因?yàn)閿?shù)據(jù)較多,循環(huán)過程中,利用xpath定位的節(jié)點(diǎn)位置有時(shí)會(huì)不一致:評(píng)分為空時(shí)節(jié)點(diǎn)位置是沒有顯示的,會(huì)導(dǎo)致抓取的元素為日期。為評(píng)分出錯(cuò),導(dǎo)致后面無法分析,在抓取時(shí)直接利用循環(huán)遍歷,將錯(cuò)誤元素賦值為null,具體代碼為:
grade = []
for i in gra:
if len(i) > 4:
i = "null"
grade.append(i)
(2)影評(píng)主要由作者,評(píng)分和內(nèi)容三部分組成,如果內(nèi)容存在缺失,不僅會(huì)導(dǎo)致錯(cuò)位,而且會(huì)導(dǎo)致最終一一對(duì)應(yīng)時(shí)報(bào)錯(cuò),則需要對(duì)每一頁(yè)內(nèi)容循環(huán)遍歷,如若為空列表,則賦值為null,具體代碼為:
content = []
for c in range(1, 21):
con=html.xpath('//*[@id="comments"]/div[{}]/div[2]/p/span/text()'.format(c))
if con == []:
con = ['null']
content.append(con[0])
(3)對(duì)于爬取下來的評(píng)分等級(jí),需要進(jìn)行計(jì)數(shù)處理,方便之后的可視化展示,則需要用到pandas的value_counts()方法對(duì)等級(jí)進(jìn)行計(jì)數(shù)統(tǒng)計(jì),其方法可以自動(dòng)忽略空值,并且也避免了if…else的冗余。
3 ?數(shù)據(jù)可視化
3.1 ?數(shù)據(jù)可視化的作用
數(shù)據(jù)可視化的作用可以體現(xiàn)在多方面,而本項(xiàng)目則主要有以下三個(gè)作用,分別為:
(1)更加直觀的參觀數(shù)據(jù),比如利用餅圖來分析評(píng)分等級(jí),繁冗的文字?jǐn)?shù)據(jù)就被圖形替代,能直觀看到大眾對(duì)電影的評(píng)價(jià)分布。
(2)統(tǒng)計(jì)效率更快,比如利用jieba庫(kù)分詞來統(tǒng)計(jì)詞頻,與人工統(tǒng)計(jì)相比,速度提升了不少。
(3)更加美觀的展現(xiàn)數(shù)據(jù),在(2)的基礎(chǔ)上,如果想要統(tǒng)計(jì)出來的詞頻以特定形態(tài)呈現(xiàn)出來,那么就需要用到imageio庫(kù),否則它的形狀就是一個(gè)普通的矩形。
3.2 ?設(shè)計(jì)需求
在如今的大信息時(shí)代,數(shù)據(jù)量急劇增加,數(shù)據(jù)本身的信息價(jià)值被不斷沖刷,導(dǎo)致有價(jià)值的信息被無價(jià)值的信息淹沒,所以我們需要一種更形象、具體的方式來處理這些數(shù)據(jù),使得有價(jià)值的信息被展現(xiàn)出來,而數(shù)據(jù)可視化就完全符合要求。從某種意義上來說,數(shù)據(jù)可視化就是尋找數(shù)據(jù)本身中隱藏的某種規(guī)律及現(xiàn)象,通過圖表的方式來總結(jié)復(fù)雜數(shù)據(jù),要比書面信息更利于人腦的吸收[7]。所以本項(xiàng)目對(duì)數(shù)據(jù)做了以下處理:
對(duì)爬取下來的每部電影前500條,四部共2 000條短評(píng)內(nèi)容存入csv文件,然后讀取評(píng)分等級(jí)那一列數(shù)據(jù),利用pandas的value_counts()方法對(duì)五個(gè)不同的評(píng)分等級(jí)“很差、較差、還行、推薦、力薦”進(jìn)行數(shù)據(jù)統(tǒng)計(jì),由得到的統(tǒng)計(jì)數(shù)據(jù)繪制餅圖來體現(xiàn)大家對(duì)《小時(shí)代》系列的評(píng)星看法。
運(yùn)用jieba庫(kù)對(duì)爬取到的短評(píng)內(nèi)容進(jìn)行詞頻統(tǒng)計(jì),將統(tǒng)計(jì)結(jié)果存入txt文件,再利用wordcloud庫(kù)繪制詞云圖,然后用Matplotlib庫(kù)出現(xiàn)頻率排行前十的詞語(yǔ)做一個(gè)直方圖的繪制。
3.3 ?相關(guān)技術(shù)
數(shù)據(jù)可視化部分利用codecs.open(filepath,method,encoding)打開文件;jieba庫(kù)進(jìn)行分詞便于后續(xù)利用wordcloud做詞云圖,利用Imageio控制詞云圖形狀。最后利用matplotlib庫(kù)做數(shù)據(jù)的條形圖draw_barh()、餅圖draw_pie()。
3.4 ?具體實(shí)現(xiàn)
3.4.1 ?詞頻條形圖
利用jieba中文詞庫(kù)自動(dòng)進(jìn)行分詞處理,并利用Counter()方法統(tǒng)計(jì)其出現(xiàn)的次數(shù),將非中文字符的分詞刪除,將處理好的詞頻存放在文件里面并繪制頻率為前十的條形圖,條形圖的X軸設(shè)置為出現(xiàn)次數(shù),呈現(xiàn)方式如圖1所示。
3.4.2 ?詞云圖
為了將之前分割的詞以特定的形式呈現(xiàn)出來,需要使用一張背景圖片來加工,利用pac_mask = imageio.imread (r'xiaoshidai.png')增加一個(gè)背景圖片,并在WordCloud()中加入?yún)?shù)mask,以此可自定義繪制詞云圖,呈現(xiàn)形式如圖2所示。
3.4.3 ?餅圖
由數(shù)據(jù)清洗得到大眾對(duì)電影的5個(gè)等級(jí),用這5個(gè)等級(jí)繪制出餅圖,突出顯示百分比最高的一個(gè)等級(jí),呈現(xiàn)形式如圖3所示。
3.5 ?可視化結(jié)論
利用餅圖繪制評(píng)分等級(jí)后發(fā)現(xiàn)等級(jí)為“很差”的占比最多,這說明在大眾心里這一系列電影無疑是非常爛的電影,利用jieba詞庫(kù)及條形圖統(tǒng)計(jì)出來影評(píng)中高頻率詞語(yǔ)中有作者人名,同時(shí)他也是這系列劇的導(dǎo)演,據(jù)了解,他之前是一名青春文學(xué)作家,不少人讀過他的小說,算得上是他的粉絲,可以說名氣很大,意味著可能大部分觀眾是沖著這位名氣甚大的作家去看的;通過抓取下來的劇照可以發(fā)現(xiàn),劇中場(chǎng)景華麗,明星陣容超強(qiáng),通過抓取下來的歌曲可以發(fā)現(xiàn),演唱者大多在當(dāng)時(shí)名氣不小,正是因?yàn)橛辛藦?qiáng)大的粉絲團(tuán)以及明星效應(yīng)引起的轟動(dòng),再加上小說的渲染,才成就了這系列電影的高票房。這也就是為什么如今頻繁出現(xiàn)爛片高票房的原因了。
4 ?結(jié) ?論
本文以豆瓣網(wǎng)站《小時(shí)代》系列電影為例,完成了對(duì)特定主題網(wǎng)絡(luò)爬蟲的數(shù)據(jù)采集、數(shù)據(jù)清洗以及數(shù)據(jù)可視化展示三部分,闡明了具體的設(shè)計(jì)背景以及設(shè)計(jì)思路,并編寫完成了數(shù)據(jù)采集、數(shù)據(jù)清洗、數(shù)據(jù)可視化三個(gè)部分的代碼。根據(jù)對(duì)系列電影影評(píng)、劇照及音樂的爬取,對(duì)其數(shù)據(jù)進(jìn)行清洗并將部分?jǐn)?shù)據(jù)進(jìn)行可視化分析,可以解釋部分影視作品評(píng)價(jià)不高卻任然能夠吸引觀眾去觀看。因?yàn)樵谂廊∮霸u(píng)時(shí)內(nèi)容較多,雖然在代碼中加入了多線程爬蟲,但可以后期加以調(diào)試,對(duì)比得到時(shí)間花費(fèi)較短的結(jié)果,以此來提高網(wǎng)絡(luò)爬蟲的效率。另外豆瓣網(wǎng)在同一賬戶登錄頻率較高時(shí)會(huì)設(shè)置滑塊驗(yàn)證,本項(xiàng)目雖然利用了Selenium模擬瀏覽器進(jìn)行自動(dòng)登錄,但是不能解決滑塊驗(yàn)證即還會(huì)手動(dòng)點(diǎn)擊滑塊獲取驗(yàn)證,針對(duì)這一問題,后期可以通過自主學(xué)習(xí),設(shè)計(jì)全自動(dòng)化板塊,以此來消除人工參與問題,達(dá)到自動(dòng)化效果,進(jìn)而提升效率。
參考文獻(xiàn):
[1] 溫佐承,賈雪.基于Python的網(wǎng)絡(luò)爬取 [J].電腦編程技巧與維護(hù),2020(12):23-24+32.
[2] 趙文杰,古榮龍.基于Python的網(wǎng)絡(luò)爬蟲技術(shù) [J].河北農(nóng)機(jī),2020(8):65-66.
[3] 劉石磊.對(duì)反爬蟲網(wǎng)站的應(yīng)對(duì)策略 [J].電腦知識(shí)與技術(shù),2017,13(15):19-21+23.
[4] 伏康,杜振鵬.網(wǎng)站反爬蟲策略的分析與研究 [J].電腦知識(shí)與技術(shù),2019,15(28):28-30.
[5] 陳利婷.大數(shù)據(jù)時(shí)代的反爬蟲技術(shù) [J].電腦與信息技術(shù),2016,24(6):60-61.
[6] 張巖.大數(shù)據(jù)反爬蟲技術(shù)分析 [J].信息系統(tǒng)工程,2018(8):130.
[7] 朱寅非.數(shù)據(jù)可視化應(yīng)用領(lǐng)域及作用 [J].電子技術(shù)與軟件工程,2020(16):149-150.
作者簡(jiǎn)介:黃蓉(1999—),女,漢族,四川成都人,本科在讀,研究方向:大數(shù)據(jù)分析;毛紅霞(1981—),女,漢族,寧夏石嘴山人,副教授,碩士,研究方向:大數(shù)據(jù)、人工智能。