![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLjNTOlBzN2EDNwUGZmZzN3UzMmJDZwAzYzMWY0ETZ0ImZ2kzMycTMy8CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.png)
并沒有成功爬到所有的短評,一波三折,最終隻爬到了500條,當然這也是豆瓣目前可見的最大數量,本文将細緻分析爬蟲的整個過程,并對爬到的資料加以分析,蟻小見大。
整篇文章共包含爬和文本分析兩部分,因為爬到的資料包含資訊較少,是以分析過程相對簡單,包含描述統計分析、情感分析和分詞詞雲,主要代碼在各部分給出,需要完整代碼和爬到的資料請在背景回複"蟻人2爬蟲",可以直接運作。
1. 爬蟲部分
首先說明一下目标和工具
軟體:python3.6
packages:selenium jieba snownlp wordcloud
後三個是之後文本分析用的。
目标網址:
https://movie.douban.com/subject/26636712/comments?status=P
豆瓣上的影評分兩種,一種是長篇大論的影評,還有一種是短評,類似上圖中,這次爬蟲的目标就是上圖中紅色框線中的短評,資訊包括使用者名,星級評價,日期,有用數,評論正文,雖說首頁顯示45576條,但其實可見的隻有500條,每頁是20條短評,多一條都不給,手動去點,點到25頁之後就沒有任何資訊了。
第一遍直接用selenium去爬隻爬到了200條,200條之後就自動停止了,後來檢查了半天發現必須登入豆瓣上去才能看到更多的評論,然後又加了登陸的代碼,後來嘗試過程中登陸的太多又有了驗證碼,又加了一個手動輸入驗證碼的部分,最終成功爬到了500條,因為之前沒有處理過登陸相關的,是以折騰了很長時間,整體過程如下。
登陸
登陸頁面是豆瓣首頁https://www.douban.com/,并不是我們爬取的網站,是以首先通過selenium模拟登陸之後,再擷取蟻人2短評頁面進行爬蟲。
通過chrome開發者工具獲得賬戶名,密碼,驗證碼的位置,賬戶名和密碼直接輸入,驗證碼擷取圖檔後先存到本地,打開後手動輸入,輸入之後關掉驗證碼圖檔,代碼繼續執行,就登入成功了,剛開始登的時候不需要驗證碼。
賬戶名位置
代碼如下:
1def gethtml(url):
2 loginurl='https://www.douban.com/' # 登入頁面
3
4 browser = webdriver.PhantomJS()
5 browser.get(loginurl) # 請求登入頁面
6 browser.find_element_by_name('form_email').clear() # 擷取使用者名輸入框,并先清空
7 browser.find_element_by_name('form_email').send_keys(u'你的使用者名') # 輸入使用者名
8 browser.find_element_by_name('form_password').clear() # 擷取密碼框,并清空
9 browser.find_element_by_name('form_password').send_keys(u'你的密碼') # 輸入密碼
10
11 # 驗證碼手動處理,輸入後,需要将圖檔關閉才能繼續執行下一步
12 captcha_link = browser.find_element_by_id('captcha_image').get_attribute('src')
13 urllib.request.urlretrieve(captcha_link,'captcha.jpg')
14 Image.open('captcha.jpg').show()
15 captcha_code = input('Pls input captcha code:')
16 browser.find_element_by_id('captcha_field').send_keys(captcha_code)
17
18 browser.find_element_by_css_selector('input[class="bn-submit"]').click()
19 browser.get(url)
20 browser.implicitly_wait(10)
21 return(browser)
爬短評
登入之後,轉到我們要爬的蟻人2短評頁面,爬完一頁之後,找到後頁的位置click跳轉到下一頁繼續爬,循環一直到最後一頁,從開發者工具可以看到,第一頁的後頁xpath是"//*[@id='paginator']/a",之後每一頁的後頁的xpath都是"//*[@id='paginator']/a[3]",但最後一頁的xpath不為這兩個,是以可以通過循環的方式,第一頁之後,隻要"//*[@id='paginator']/a[3]"找得到,就跳轉到下一頁繼續爬,直到找不到為止。
具體爬的時候,用一個dataframe來存所有的資訊,一行為一個使用者的所有資料,資料位置仍然通過開發者工具獲得,細節不再贅述。
代碼如下:
1def getComment(url):
2 i = 1
3 AllArticle = pd.DataFrame()
4 browser = gethtml(url)
5 while True:
6 s = browser.find_elements_by_class_name('comment-item')
7 articles = pd.DataFrame(s,columns = ['web'])
8 articles['uesr'] = articles.web.apply(lambda x:x.find_element_by_tag_name('a').get_attribute('title'))
9 articles['comment'] = articles.web.apply(lambda x:x.find_element_by_class_name('short').text)
10 articles['star'] = articles.web.apply(lambda x:x.find_element_by_xpath("//*[@id='comments']/div[1]/div[2]/h3/span[2]/span[2]").get_attribute('title'))
11 articles['date'] = articles.web.apply(lambda x:x.find_element_by_class_name('comment-time').get_attribute('title'))
12 articles['vote'] = articles.web.apply(lambda x:np.int(x.find_element_by_class_name('votes').text))
13 del articles['web']
14 AllArticle = pd.concat([AllArticle,articles],axis = 0)
15 print ('第' + str(i) + '頁完成!')
16
17 try:
18 if i==1:
19 browser.find_element_by_xpath("//*[@id='paginator']/a").click()
20 else:
21 browser.find_element_by_xpath("//*[@id='paginator']/a[3]").click()
22 browser.implicitly_wait(10)
23 time.sleep(3) # 暫停3秒
24 i = i + 1
25 except:
26 AllArticle = AllArticle.reset_index(drop = True)
27 return AllArticle
28 AllArticle = AllArticle.reset_index(drop = True)
29 return AllArticle
調用以上兩個函數爬取資料,其實對于豆瓣上别的電影影評,估計稍微改一改也可以爬了。
1url = 'https://movie.douban.com/subject/26636712/comments?status=P'
2result = getComment(url)
最終爬下來的資料大概是這樣子。
2. 文本分析
描述統計分析
首先看一看拿到的樣本中各星級評價的分布情況,None表示沒有星級評價。
整體來看,三星四星評價巨多,說明大家對于蟻人2整體評價還不錯。
再來看看哪些短評大家最認可,投票數最多。
嗯,怎麼說呢...
初代黃蜂女的扮演者米歇爾·菲佛也成功引起了廣大影迷的注意力。
情感分析
情感分析做的比較簡單,主要借助于snownlp包,對于評論的情感傾向進行評分,0-1之間,越正面的情感傾向對應的分值越高,不過根據官方說明,這裡用到的模型是用購物評價資料訓練出來的,用到這裡可能誤差會有些大, 姑且一試吧,感覺效果還可以。
1# 情感分析
2def sentiment(content):
3 s = SnowNLP(str(content))
4 return s.sentiments
5
6
7result['sentiment'] = result.comment.apply(sentiment)
8
9# 負面評價
10result.sort(['sentiment'],ascending = True)[:10][['comment','sentiment']]
11
12# 正面評價
13result.sort(['sentiment'],ascending = False)[:10][['comment','sentiment']]
先來看看正面評價,sentiment表示情感得分。
恩,看上去正面評價基本都是高星級評分的觀衆給出的,有理有據,令人信服。再來看看負面評價。
分詞詞雲
通過jieba進行分詞,根基TF-IDF算法提取關鍵詞,代碼及部分關鍵詞如下。
1texts = ';'.join(result.comment.tolist())
2cut_text = " ".join(jieba.cut(texts))
3keywords = jieba.analyse.extract_tags(cut_text, topK=500, withWeight=True, allowPOS=('a','e','n','nr','ns'))
4
5
6ss = pd.DataFrame(keywords,columns = ['詞語','重要性'])
7
8fig = plt.axes()
9plt.barh(range(len(ss.重要性[:20][::-1])),ss.重要性[:20][::-1],color = 'darkred')
10fig.set_yticks(np.arange(len(ss.重要性[:20][::-1])))
11fig.set_yticklabels(ss.詞語[:20][::-1],fontproperties=font)
12fig.set_xlabel('Importance')
13
14alice_mask = np.array(Image.open( "yiren.jpg"))
15text_cloud = dict(keywords)
16cloud = WordCloud(
17 width = 600,height =400,
18 font_path="STSONG.TTF",
19 # 設定背景色
20 background_color='white',
21
22 mask=alice_mask,
23 #允許最大詞彙
24 max_words=500,
25 #最大号字型
26 max_font_size=150,
27 #random_state=777,
28 # colormap = 'Accent_r'
29 )
30
31
32
33plt.figure(figsize=(12,12))
34word_cloud = cloud.generate_from_frequencies(text_cloud)
35plt.imshow(word_cloud)
36plt.axis('off')
37plt.show()
關鍵詞
分詞結果來看,"彩蛋"毫無疑問是是蟻人2中大家最關心的點。最後,以蟻人分詞詞雲作為文章結尾!
原文釋出時間為:2018-09-12
本文作者:量化小白H
本文來自雲栖社群合作夥伴“
CDA資料分析師”,了解相關資訊可以關注“
”。