日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
我用Python爬了鹿晗、關(guān)曉彤微博的熱門評(píng)論,并進(jìn)行了情感分析

 相信最近科技圈都在調(diào)侃一件事:10 月 8 日中午的一條微博,引發(fā)了一場(chǎng)新浪微博用戶們(尤其是女性用戶)之間的軒然大波,導(dǎo)致新浪微博癱瘓。

本文主要涉及知識(shí)點(diǎn)包括新浪微博爬蟲、Python 對(duì)數(shù)據(jù)庫(kù)的簡(jiǎn)單讀寫、簡(jiǎn)單的列表數(shù)據(jù)去重和自然語(yǔ)言處理(snowNLP 模塊、機(jī)器學(xué)習(xí))。適合有一定編程基礎(chǔ),并對(duì) Python 有所了解的盆友閱讀。

這條微博的始作俑者,就是全球超人氣偶像明星鹿晗。

程序員們紛紛開啟了科學(xué)地討論:

詳細(xì)內(nèi)容可見昨日的圖文:鹿晗是如何將微博服務(wù)器搞炸的?

微博工程師是如何一邊結(jié)婚一邊加班的:

淘寶程序員是如何原諒鹿晗的:

在這一刻,全世界都知道鹿晗戀愛了:

全球的女鹿飯們一起失戀了。

那么鹿晗的粉絲們情緒如何呢?我們來(lái)分析一下鹿晗戀情微博的評(píng)論,分析評(píng)論時(shí)粉絲們的心情狀態(tài),且聽我娓娓道來(lái)。(想看分析結(jié)果的可直接跳到第 5 節(jié))

新浪微博 API

在經(jīng)歷了幾次爬蟲被禁的悲痛(真的很痛)之后,我學(xué)會(huì)了在爬網(wǎng)站之前先查有沒(méi)有 API 的“優(yōu)良”習(xí)慣。

新浪作為一個(gè)大廠,怎么會(huì)不推出新浪微博 API 呢,面向開發(fā)者新浪有自己的開放平臺(tái),這里是 Python 調(diào)用微博 API 的方法,通過(guò)登錄 App_key 和 App_secret 方式訪問(wèn)微博 API 的代碼,代碼是基于 PY2 的。PY3 對(duì) Weibo 模塊使用存在一定問(wèn)題。

 
 
 
 
  1. from weibo import APIClient  
  2. import webbrowser 
  3.  
  4.  
  5. import sys  
  6. reload(sys)  
  7. sys.setdefaultencoding('utf-8') 
  8.  
  9.  
  10. APP_KEY = '你的App Key ' #獲取的App Key  
  11. APP_SECRET = '你的AppSecret' #獲取的AppSecret  
  12. CALLBACK_URL = 'https://api.weibo.com/oauth2/default.html' #回調(diào)鏈接 
  13.  
  14.  
  15. client = APIClient(app_key=APP_KEY, app_secret=APP_SECRET, redirect_uri=CALLBACK_URL)  
  16. url = client.get_authorize_url()  
  17. webbrowser.open_new(url) #打開默認(rèn)瀏覽器獲取code參數(shù) 
  18.  
  19.  
  20. print '輸入url中code后面的內(nèi)容后按回車鍵:' 
  21.  
  22.  
  23. code = raw_input()  
  24. r = client.request_access_token(code)  
  25. access_token = r.access_token  
  26. expires_in = r.expires_in  
  27. client.set_access_token(access_token, expires_in) 

知道如何登錄 API 了,辣么如何調(diào)用 API 爬單條微博的評(píng)論呢?一行代碼搞定。

 
 
 
 
  1. r = client.comments.show.get(id = 4160547165300149,count = 200,page = 1) 

所有關(guān)于單條微博的評(píng)論信息都在 r.comments 中了,這里需要對(duì)照微博 API 文檔,微博 API 有聲明調(diào)用微博評(píng)論 API 需要獲取用戶授權(quán)。

但是捏,只要知道單條微博的 id,就可以調(diào)用這個(gè) API 了,關(guān)于單條微博的 id 如何獲取在后面會(huì)說(shuō)(小聲一點(diǎn),千萬(wàn)別讓微博知道,萬(wàn)一封了呢)。

按照 client. 接口名 .get(請(qǐng)求參數(shù))的方式獲取 API,獲取 API 后的規(guī)格可在接口詳情中查看,文檔中有給出返回結(jié)果的示例。

文檔中也給出了關(guān)鍵數(shù)據(jù)的 json 接口名稱。

如果我們要獲取微博評(píng)論的內(nèi)容,只需要調(diào)用 text 接口即可。

 
 
 
 
  1. for st in r.comments:  
  2. text = st.text 

微博爬蟲

通過(guò)調(diào)用新浪微博 API 的方式,我們就可以簡(jiǎn)單獲取單條微博的評(píng)論信息了,為啥說(shuō)簡(jiǎn)單呢,因?yàn)槿思t信息貴啊!

你以為大 V 的微博就這么免費(fèi)的給你 API 調(diào)用了嗎,非認(rèn)證應(yīng)用開發(fā)者單日只能請(qǐng)求千次 API,這對(duì)像鹿晗這樣單條微博幾十萬(wàn)評(píng)論的大 V 來(lái)說(shuō)…太少了(TT)

所以捏,還是要寫微博爬蟲。

正所謂,知己知彼百戰(zhàn)不殆,新浪作為大廠,怎么說(shuō)也是身經(jīng)百戰(zhàn),必定是經(jīng)歷了無(wú)數(shù)場(chǎng)爬蟲與反爬之間的戰(zhàn)爭(zhēng),必然有著健全的反爬策略。正所謂,強(qiáng)敵面前,繞道而行,有位大佬說(shuō)得好,爬網(wǎng)站,先爬移動(dòng)端:https://m.weibo.cn/

登錄微博后,進(jìn)入到鹿晗公布戀情的微博中去,_(:зゝ∠)_ 已經(jīng)有 200w+ 評(píng)論了,可以看到安靜的微博下粉絲們不安的心…

移動(dòng)端微博的網(wǎng)址顯得肥腸簡(jiǎn)單,不似 PC 端那么復(fù)雜而不明邏輯:https://m.weibo.cn/status/4160547165300149

多點(diǎn)幾條微博就可以知道 status 后面的數(shù)字,就是單條微博的 id 了。

評(píng)論里包含了熱門評(píng)論和***評(píng)論兩種,但無(wú)論是哪種評(píng)論,繼續(xù)往下翻,網(wǎng)址都不會(huì)變化。在 chrome 瀏覽器右鍵“檢查”,觀察 Network 變化。

從 Network 的 xhr 文件中,可以得知熱門評(píng)論的變化規(guī)律是:

 
 
 
 
  1. 'https://m.weibo.cn/single/rcList?format=cards&id=' + 單條微博id + '&type=comment&hot=1&page=' + 頁(yè)碼 

***評(píng)論的變化規(guī)律是:

'https://m.weibo.cn/api/comments/show?id=' + 單條微博id + '&page=' + 頁(yè)碼

打開

https://m.weibo.cn/single/rcList?format=cards&id=4154417035431509&type=comment&hot=1&page=1 就可以看到熱門評(píng)論的 json 文件。

接下來(lái)就是套路了,偽裝瀏覽器 header,讀取 json 文件,遍歷每一頁(yè)…這都不是重點(diǎn)!直接上代碼~這里開始是 PY3 的代碼了~

 
 
 
 
  1. import re,time,requests,urllib.request 
  2.  
  3.  
  4. weibo_id = input('輸入單條微博ID:')  
  5. # url='https://m.weibo.cn/single/rcList?format=cards&id=' + weibo_id + '&type=comment&hot=1&page={}' #爬熱門評(píng)論 
  6. url='https://m.weibo.cn/api/comments/show?id=' + weibo_id + '&page={}' #爬時(shí)間排序評(píng)論  
  7. headers = { 
  8.    'User-agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:55.0) Gecko/20100101 Firefox/55.0', 
  9.    'Host' : 'm.weibo.cn', 
  10.    'Accept' : 'application/json, text/plain, */*', 
  11.    'Accept-Language' : 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3', 
  12.    'Accept-Encoding' : 'gzip, deflate, br', 
  13.    'Referer' : 'https://m.weibo.cn/status/' + weibo_id, 
  14.    'Cookie' : '登錄cookie信息', 
  15.    'DNT' : '1', 
  16.    'Connection' : 'keep-alive', 
  17.    } 
  18. i = 0 
  19. comment_num = 1 
  20. while True: 
  21.    # if i==1:     #爬熱門評(píng)論 
  22.    #     r = requests.get(url = url.format(i),headers = headers) 
  23.    #     comment_page = r.json()[1]['card_group'] 
  24.    # else: 
  25.    #     r = requests.get(url = url.format(i),headers = headers) 
  26.    #     comment_page = r.json()[0]['card_group'] 
  27.    r = requests.get(url = url.format(i),headers = headers)  #爬時(shí)間排序評(píng)論 
  28.    comment_page = r.json()['data'] 
  29.    if r.status_code ==200: 
  30.        try: 
  31.            print('正在讀取第 %s 頁(yè)評(píng)論:' % i) 
  32.            for j in range(0,len(comment_page)): 
  33.                print('第 %s 條評(píng)論' % comment_num) 
  34.                user = comment_page[j] 
  35.                comment_id = user['user']['id'] 
  36.                print(comment_id) 
  37.                user_name = user['user']['screen_name'] 
  38.                print(user_name) 
  39.                created_at = user['created_at'] 
  40.                print(created_at) 
  41.                text = re.sub('<.*?>|回復(fù)<.*?>:|[\U00010000-\U0010ffff]|[\uD800-\uDBFF][\uDC00-\uDFFF]','',user['text']) 
  42.                print(text) 
  43.                likenum = user['like_counts'] 
  44.                print(likenum) 
  45.                source = re.sub('[\U00010000-\U0010ffff]|[\uD800-\uDBFF][\uDC00-\uDFFF]','',user['source']) 
  46.                print(source + '\r\n') 
  47.                comment_num+=1 
  48.            i+=1 
  49.            time.sleep(3) 
  50.        except:
  51.            i+1 
  52.            pass 
  53.    else: 
  54.        break 

這里有四點(diǎn)說(shuō)明:

  • 設(shè)置爬取間隔時(shí)間之后,微博爬蟲被禁的概率降低了很多(特別是晚上)。
  • 新浪每次返回的 json 數(shù)據(jù)條數(shù)隨機(jī),所以翻頁(yè)之后會(huì)出現(xiàn)數(shù)據(jù)重復(fù)的情況,所以用到了數(shù)據(jù)去重,這會(huì)在后面說(shuō)。
  • 在 text 和 source 中添加了去除 emoji 表情的代碼(折騰了很久寫不進(jìn)數(shù)據(jù)庫(kù),差點(diǎn)就從刪庫(kù)到跑路了/(ㄒoㄒ)/),同時(shí)也去除了摻雜其中的回復(fù)他人的 html 代碼。
  • 我只寫了讀取數(shù)據(jù),沒(méi)有寫如何保存,因?yàn)槲覀円玫綌?shù)!據(jù)!庫(kù)!辣!(這是重點(diǎn)!敲黑板)

Python 中數(shù)據(jù)庫(kù)的讀取與寫入

雖然微博爬蟲大大提高了數(shù)據(jù)獲取量,但也因?yàn)槭桥老x而容易被新浪封禁。

這里結(jié)束循環(huán)的判斷是網(wǎng)絡(luò)狀態(tài)不是 200,但當(dāng)微博發(fā)現(xiàn)是爬蟲時(shí),微博會(huì)返回一個(gè)網(wǎng)頁(yè),網(wǎng)頁(yè)中什么實(shí)質(zhì)內(nèi)容都木有,這時(shí)候程序就會(huì)報(bào)錯(cuò),而之前爬到的數(shù)據(jù),就啥也沒(méi)有了。

但是如果爬一會(huì),保存一次數(shù)據(jù),這數(shù)據(jù)量要一大起來(lái)…冷冷的文件在臉上胡亂地拍…我的心就像被…這時(shí)候我們就需要用到數(shù)據(jù)庫(kù)了。

數(shù)據(jù)庫(kù),顧名思義,就是存放數(shù)據(jù)的倉(cāng)庫(kù),數(shù)據(jù)庫(kù)作為一個(gè)發(fā)展了 60 多年的管理系統(tǒng),有著龐大的應(yīng)用領(lǐng)域和復(fù)雜的功能……好了我編不下去了。

在本文中,數(shù)據(jù)庫(kù)的主要作用是 AI 式的 excel 表格(●—●)。在爬蟲進(jìn)行的過(guò)程中,爬到一個(gè)數(shù)就存進(jìn)去,爬到一個(gè)數(shù)就存進(jìn)去,即使爬蟲程序運(yùn)行中斷,中斷前爬到的數(shù)據(jù)都會(huì)存放在數(shù)據(jù)庫(kù)中。

大多數(shù)數(shù)據(jù)庫(kù)都能與 Python 對(duì)接使用的,米醬知道的有 MySQL、SQLite、Mongodb、Redis。

這里用的是 MySQL,Mac上 MySQL 的安裝,管理數(shù)據(jù)庫(kù)的軟件 Navicat 使用幫助,其他系統(tǒng)自己找吧,安裝使用過(guò)程中有啥問(wèn)題,請(qǐng)不要來(lái)找我(逃

根據(jù)上面的代碼,在 navicat 中創(chuàng)建數(shù)據(jù)庫(kù)、表和域以及域的格式。在 Python 程序中添加代碼。

 

 
 
 
 
  1. conn =pymysql.connect(host='服務(wù)器IP(默認(rèn)是127.0.0.1)',user='服務(wù)器名(默認(rèn)是root)',password='服務(wù)器密碼',charset="utf8",use_unicode = False)    #連接服務(wù)器 
  2. cur = conn.cursor() 
  3. sql = "insert into nlp.love_lu(comment_id,user_name,created_at,text,likenum,source) values(%s,%s,%s,%s,%s,%s)" #格式是:數(shù)據(jù)名.表名(域名) 
  4. param = (comment_id,user_name,created_at,text,likenum,source) 
  5. try: 
  6.    A = cur.execute(sql,param) 
  7.    conn.commit() 
  8. except Exception as e: 
  9.    print(e) 
  10.    conn.rollback() 

運(yùn)行 Python 程序,大概爬了 1w 條實(shí)時(shí)評(píng)論,在進(jìn)行下一步研究之前,我們還要將數(shù)據(jù)庫(kù)中的內(nèi)容讀取出來(lái),Python 中數(shù)據(jù)庫(kù)的讀取代碼也很簡(jiǎn)單。

 
 
 
 
  1. conn =pymysql.connect(host='服務(wù)器IP',user='用戶名',password='密碼',charset="utf8")    #連接服務(wù)器  
  2. with conn:  
  3.    cur = conn.cursor() 
  4.    cur.execute("SELECT * FROM nlp.love_lu WHERE id < '%d'" % 10000) 
  5.    rows = cur.fetchall() 

這樣之前爬取的信息就被讀取出來(lái)了,但是前面也說(shuō)了,微博爬蟲翻頁(yè)時(shí)返回?cái)?shù)據(jù)條數(shù)隨機(jī),所以會(huì)出現(xiàn)重復(fù)的狀況,所以讀取之后,需要用 if…not in 語(yǔ)句進(jìn)行一個(gè)數(shù)據(jù)去重。

 
 
 
 
  1. for row in rows: 
  2.    row = list(row) 
  3.    del row[0] 
  4.    if row not in commentlist: 
  5.        commentlist.append([row[0],row[1],row[2],row[3],row[4],row[5]]) 

完整代碼在文末。

自然語(yǔ)言處理 NLP

NLP 是人工智能的一個(gè)領(lǐng)域,可以通過(guò)算法的設(shè)計(jì)讓機(jī)器理解人類語(yǔ)言,自然語(yǔ)言也屬于人工智能中較為困難的一環(huán)。

像中文這么博大精深、變幻莫測(cè)的語(yǔ)言更是 NLP 中的一大難點(diǎn),Python 中有很多 NLP 相關(guān)的模塊,有興趣的盆友可以通過(guò)用 Python 實(shí)現(xiàn)簡(jiǎn)單的文本情感分析初探 NLP。

我參(ban)考(yun)了一些現(xiàn)成的情感分析算法,對(duì)爬取的評(píng)論進(jìn)行分析,錯(cuò)誤率肥腸高_(dá)(:зゝ∠)_ ,這可腫么辦?難道要重新設(shè)計(jì)算法?我仿佛遇到了人生中***個(gè)因?yàn)檎Z(yǔ)文沒(méi)學(xué)好而引發(fā)的重大問(wèn)題……

當(dāng)然像我這樣靈(lan)活(duo)的姑娘,自然是很快發(fā)現(xiàn)了 Python 中較為出名的一個(gè)中文 NLP 庫(kù):snowNLP。snowNLP 調(diào)用的方法比較簡(jiǎn)單,源碼中詳細(xì)解釋了調(diào)用方法和生成結(jié)果。

 
 
 
 
  1. def snowanalysis(textlist): 
  2.    sentimentslist = [] 
  3.    for li in textlist: 
  4.        s = SnowNLP(li) 
  5.        print(li) 
  6.        print(s.sentiments) 
  7.        sentimentslist.append(s.sentiments) 

這段代碼中獲取了讀取數(shù)據(jù)庫(kù)后由評(píng)論主體 text 生成的列表文件,并依次對(duì)每一個(gè)評(píng)論進(jìn)行情感值分析。

snowNLP 能夠根據(jù)給出的句子生成一個(gè) 0-1 之間的值,當(dāng)值大于 0.5 時(shí)代表句子的情感極性偏向積極,當(dāng)分值小于 0.5 時(shí),情感極性偏向消極,當(dāng)然越偏向倆頭,情緒越明顯咯,讓我們來(lái)看看測(cè)試評(píng)論的結(jié)果。

可以從文字內(nèi)容和下面對(duì)應(yīng)的數(shù)值看出,祝福或者表現(xiàn)的積極的情緒,分值大多高于 0.5,而期盼分手或者表達(dá)消極情緒的分值,大多低于 0.5。分析結(jié)果中也存在一定的誤差,可以通過(guò)訓(xùn)練對(duì)算法進(jìn)行優(yōu)化,米醬語(yǔ)文不好就不瞎搞了…(逃

分析結(jié)果

讓我們來(lái)看看本次分析的結(jié)果(●—●)。

 
 
 
 
  1. plt.hist(sentimentslist,bins=np.arange(0,1,0.02)) 
  2. plt.show() 

對(duì)上節(jié)經(jīng)過(guò)處理得到的情感值列表進(jìn)行統(tǒng)計(jì),并生成分布圖。下圖數(shù)據(jù)采集時(shí)間 10 月 9 日 19 時(shí),采集評(píng)論 1w 條。

↑鹿晗宣布戀愛微博評(píng)論情感值分布

再看看關(guān)曉彤回應(yīng)的微博情況。

↑關(guān)曉彤對(duì)應(yīng)微博評(píng)論情感值分布

根據(jù)這兩張圖,可以看到情感值在接近 0、1 兩端以及 0.5 左右位置頻率較高,說(shuō)明粉絲們對(duì)于此類事件的情緒無(wú)論是積極還是消極都是比較明顯的。但也可以看出,積極的情緒更多于消極的情緒。

我又對(duì)評(píng)論中出現(xiàn)的微博表情進(jìn)行了統(tǒng)計(jì)。

給鹿晗的評(píng)論中表情的數(shù)量是關(guān)曉彤的近 3 倍,而排在***位的,都是 [加油],可以看到粉絲們對(duì)鹿晗的戀情還是支持居多的,當(dāng)然也不乏有些人想要 [bm投訴] 主角們了,也有部分人感到 [悲傷],想要冷靜一下 [別煩我]。

再對(duì)評(píng)論內(nèi)容進(jìn)行一下詞云分析。

↑鹿晗宣布戀愛微博評(píng)論詞云

↑關(guān)曉彤對(duì)應(yīng)微博評(píng)論詞云

在鹿晗的微博下面出現(xiàn)了大量的祝福、支持、一起等詞匯,也有一些為什么、不配、分手之類質(zhì)疑的聲音;在關(guān)曉彤的微博下面也存在相同的詞匯,但是好像還有大量的關(guān)于熱巴、李易峰的字眼,看來(lái)兩位都有緋聞 CP 呀。

你們猜詞云的背景圖是什么?我就不說(shuō)了,你們自己感受。

參考資料:

1.微博開放平臺(tái):http://open.weibo.com/

2.Python調(diào)用微博API的方法:http://blog.csdn.net/gamer_gyt/article/details/51839159

3.微博API文檔:http://open.weibo.com/wiki/%E5%BE%AE%E5%8D%9AAPI

4.MySQL的安裝:http://www.jianshu.com/p/2d902dd4fff4

5.Navicat使用幫助:http://www.jianshu.com/p/326c1aaa1052

6.if…not in語(yǔ)句:http://www.cnblogs.com/ranjiewen/p/6305684.html

7.用Python實(shí)現(xiàn)簡(jiǎn)單的文本情感分析:https://zhuanlan.zhihu.com/p/23225934 

8.snowNLP:https://github.com/isnowfy/snownlp


網(wǎng)站欄目:我用Python爬了鹿晗、關(guān)曉彤微博的熱門評(píng)論,并進(jìn)行了情感分析
鏈接地址:http://m.5511xx.com/article/cdpjeoo.html