誰才是鬥魚一哥?(用Python抓取鬥魚直播間信息)
前言:
看直播已經挺久了,正好在這個暑假學習了Python爬蟲,所以想嘗試分析一下誰才是鬥魚之中觀看人數最多的主播。使用Python編寫爬蟲代碼,爬取鬥魚直播間的信息,最後結合Echarts這個神器作出圖表。
準備工作:
這次運行的代碼僅僅需要requests和BS4,都是Python爬蟲比較常見的庫,都可以用pip下載。
pip install BeautifulSoup4pip install requestspip install pymysqlpip install pyecharts
然後用Mysql存儲數據,最後分析和作圖表用了Excel和Echarts。
首先我們要分析鬥魚直播的網站結構,不管抓取什麼信息都要先分析網頁結構,找到我們需要信息的所在地方。
這次我們的目標網站是:
https://www.douyu.com/directory/all
按F12打開chrome的開發者工具,初步分析網站大概的結構,可以看到每一個直播間的信息都在<ul id="live-list-contentbox">的標籤裡面,一個<li>就包含了一個直播間的信息。我們需要的知識直播間名稱、隸屬版塊、主播還有觀看人數,分別是下圖紅圈處。
準備工作做足,接下來就是編寫代碼了。
代碼編寫:
import requestsimport reimport timefrom bs4 import BeautifulSoupimport pymysqlfrom datetime import datetimedef open_html(url): r = requests.get(url) r.encoding = utf-8 return r.textdef scrapy(url): infos = [] html = open_html(url) soup = BeautifulSoup(html, lxml) total = soup.find(ul,id=live-list-contentbox) every = total.find_all(li,attrs={data-rpos:0,data-sub_rt:0}) for li in every: #定義一個空字典 info = {} info[title] = li.find(h3).text.strip()#找到標題 info[type] = li.find(span,class_=tag ellipsis).text.strip()#找到直播版塊 info[host] = li.find(span,class_=dy-name ellipsis fl).text.strip()#找到主播 now = datetime.now() num = li.find(span,class_=dy-num fr).text if 萬 in num: num1 = num.replace(萬,) if . in num1: num2 = float(num1)*10000 info[viewer] = num2 else: num2 = int(num1)*10000 info[viewer] = num2 else: info[viewer] = num #直播間地址 info[link] = https://www.douyu.com/+str(li.find(a,class_=play-list-link)[href]) #當前時間 info[time] = now infos.append(info) print (一個房間的數據抓取完成) return infosdef PrintFile(dict): for want in dict: title = want[title] type = want[type] link = want[link] host = want[host] time = want[time] viewer = want[viewer] # 和本地的資料庫建立連接 connection = pymysql.connect( host=localhost, # 連接的是本地資料庫 user=root, # mysql用戶名 passwd=XXXX, # 密碼 db=XXXX, # 資料庫的名字 charset=utf8, # 默認的編碼方式: cursorclass=pymysql.cursors.DictCursor) with connection.cursor() as cursor: # 創建更新值的sql語句 sql = "INSERT INTO 鬥魚(title,type,link,host,viewer,time) VALUES (%s,%s,%s,%s,%s,%s)" cursor.execute(sql,(title,type,link,host,viewer,time)) # 提交本次插入的記錄 connection.commit() connection.close() print(所有直播間信息爬取完成)def main(url): content = scrapy(url) PrintFile(content) print(所有的信息都已經保存完畢!)url = https://www.douyu.com/directory/allif __name__ == __main__: for i in range(1,20): main(base_url) #抓取一次之後休眠半個小時 time.sleep(1800)
使用Mysql資料庫除了安裝Mysql之外,還可以安裝Navicat這個可視化工具,大大降低了使用難度(其實是一開始下載Mysql的時候一臉蒙蔽,完全不知道怎麼使用,後來百度知道了還有可視化工具)
安裝完之後就新建一個資料庫,然後新建一個表格,然後定義所需要的變數名和變數類型。
輸出:
結果:
程序一共爬了15天左右,不過並不是連續的,中間中斷了幾次,每天起床之後就打開程序運行(後來知道還可以把代碼放在雲伺服器運行- -,我是小白只能用笨方法了),最後抓取了大概3.7w條數據。先來看一下觀看人數的TOP 20:
好吧- -,觀看人數排行榜TOP 20都是英雄聯盟比賽的官方直播間,排行第一的是7月30號WE vs RNG的比賽,有792萬人次觀看。(時隔已經大半個月了,LPL也快要總決賽了)
為了滿足好奇心,把比賽直播間的數據剔除,再來看看主播們的觀看人數排行榜:在這份榜單中,只有兩個人,五五開和張大仙,都是他們不同直播天數的數據,由於我不怎麼玩王者榮耀,所以之前從沒注意過張大仙(但是必須承認王者榮耀真的很多人玩,群上每天都約開黑,我只能默默看著他們...)。百度了一下張大仙的資料,原來他原本是企鵝電競的大主播。張大仙在某些天數的同時段觀看人數已經超過了五五開。
不過我們也有了分析方向,張大仙和五五開都屬於19點至24點這個時間段的,那就可以來橫向比對他們每個時間點的觀看人數。
分析:
觀看人數:
選取了四天的抓取數據,分別是8月17日、8月10日、8月9日和8月8日。代碼設置了每三十分鐘運行一次,一共有10個時間點。在這裡就要強烈推薦Echarts,屬於百度的產品,可以說相較於百度全家桶,這個真是良心產品。而Python的相關庫pymysql最近更新了時間線功能Timeline(),官方文檔pyecharts詳細說明了使用方法,嘗試了一下感覺非常酷炫,很直觀顯示了數據的趨勢,可以把多個圖表按照時間線在一個圖中同時呈現,代碼和GIF圖如下:
import pyecharts as pfrom pyecharts import Timeline#這些數據是經過excel處理的attr = [19:03:00, 19:33:00, 20:03:00, 20:33:00, 21:03:00, 21:33:00, 22:03:00,22:33:00,23:03:00,23:33:00] wu1 = [34000,783000,1540000,1150000,1580000,1490000,1630000,1720000,2210000,2120000]zh1 = [2950000,3020000,2990000,2840000,3040000,2800000,2950000,2800000,2970000,2800000]line1 = p.Line(8月17號)line1.add(五五開,attr,wu1)line1.add(張大仙,attr,zh1,is_smooth=True)wu2 = [1140000,1640000,1960000,2380000,1890000,1720000,2120000,2850000,3280000,2850000]zh2 = [2300000,2530000,2770000,2760000,2690000,2690000,2690000,2680000,2760000,2800000]line2 = p.Line(8月10號)line2.add(五五開,attr,wu2)line2.add(張大仙,attr,zh2,is_smooth=True)wu3 = [1130000,2470000,2730000,2500000,2930000,3330000,3550000,3180000,2780000,2700000]zh3 = [2100000,2200000,2780000,2800000,2790000,2670000,2830000,2800000,2720000,2810000]line3 = p.Line(8月9號)line3.add(五五開,attr,wu3)line3.add(張大仙,attr,zh3,is_smooth=True)wu4 = [1140000,1940000,2590000,2550000,2220000,2540000,2660000,2420000,2520000,2450000]zh4 = [2750000,2720000,2770000,2680000,2850000,2790000,2770000,2700000,2730000,2800000]line4 = p.Line(8月8號)line4.add(五五開,attr,wu4)line4.add(張大仙,attr,zh4,is_smooth=True)timeline = Timeline(is_auto_play=False, timeline_bottom=0)timeline.add(line1, 8月17號)timeline.add(line2, 8月10號)timeline.add(line3, 8月9號)timeline.add(line4, 8月8號)timeline.render()
從圖表中我們可以看到張大仙的觀看人數簡直穩定的可怕,一直保持在260萬人次左右,而且看不出開播—直播—關播這樣的趨勢,分析的時候也一直懷疑自己是否做錯了。就算在某些時候五五開的觀看人數會超過他,但是總體上看是少於張大仙的。
彈幕:
好,除了觀看人數,我們再來看一看另一個指標,那就是彈幕。經過資料查找,發現Python連抓取彈幕的第三方庫都有,而且不止一個。這次使用的是danmu,是大神 @LittleCoder 編寫的,支持抓取鬥魚、熊貓、b站等直播網站的彈幕。在某一天,從19點49分開始,同時抓取五五開和張大仙的彈幕,在24點12分結束。
先看看代碼,代碼很簡單:
from danmu import DanMuClientimport pymysqldmc = DanMuClient(https://www.douyu.com/688)@dmc.danmudef danmu_fn(msg): client = msg[NickName] message = msg[Content] connection = pymysql.connect( host=XXXX, # 連接的是本地資料庫 user=XXXX, # mysql用戶名 passwd=XXXX, # 密碼 db=XXXX, # 資料庫的名字 charset=utf8mb4, # 默認的編碼方式,最好選這個,因為彈幕可能出現表情 cursorclass=pymysql.cursors.DictCursor) with connection.cursor() as cursor: # 創建更新值的sql語句 sql = "INSERT INTO 張大仙彈幕(client,message) VALUES (%s,%s)" cursor.execute(sql,(client,message)) # 提交本次插入的記錄 connection.commit() dmc.start(blockThread = True)
Mysql顯示的結果如下:
一頁有1000條數據,最後五五開的彈幕一共抓取了166頁,彈幕數量約為16.6萬(可能因為網路延遲而丟失某些彈幕)。
而張大仙一共抓取了171頁,最後一頁有859條,那麼他的彈幕數量約為17萬條。
總結:
從收集到的數據來看,五五開不管是觀看人數還是彈幕數量都比張大仙少一點。側面證明了王者榮耀的玩家確實非常多。但是這也無礙五五開超高人氣,畢竟五五開不僅玩英雄聯盟,幾乎所有熱門遊戲,五五開都在直播間玩過。
但是僅僅分析觀看人數和彈幕是不能準確分析直播間的人氣,畢竟還涉及很多其他因素,而且事後的分析沒有特別嚴謹的統計思路和統計方法。這僅僅是我學習Python的一個小實踐,沒有多大技術含量,很多觀點也帶有一點個人色彩,只是想分享一下自己的學習經歷,給其他人一點思路。
最後說一下:
我的專業不是學計算機的,本科專業是心理學,之前也沒有接觸過一點編程知識,這個暑假剛剛考研結束,因為選擇了心理統計方向,所以想學習一些新東西,導師本來建議我去學學R語言,但是網上都說Python會比較簡單和好用,所以最後選擇了Python。網上有很多教程,但是大多數對於我這麼一個什麼都不懂的人來說,真的很難理解,一開始學習的時候一個專業名詞就能難倒我,學習Python一直斷斷續續。
直到我在知乎上看到 @Ehco 的專欄從零開始寫Python爬蟲,那時候開始就深深愛上Python爬蟲,他的教程相比起別人都簡單明了,雖然中間還是會遇到很多不懂,但是起碼我開始能真正完成一個爬蟲程序。整個暑假都是跟著他的教程學習,雖然他不認識我,但是只要他更新了教程,我都會去點贊和學習。沒有他的教程也就沒有以後的事了,希望自己也能通過不斷的學習真正掌握Python。
最近新建立了一個公眾號,發現Python還能構建公眾號,所以自己折騰也玩了很久,已經實現了自動回復機器人、在線點歌、在線翻譯等功能。當然也想滿足自己喜歡看直播這個需要,修改了一下上面的代碼,回復主播名字就可以查看當前直播信息。
公眾號也會分享自己學習Python的經歷,有興趣可以關注一下,一起學習,希望有更多的人會愛上Python。
公眾號<萬物皆Python>:everypython
Github:feng0411/Python-Everything
推薦閱讀:
※蛇哥攤上大事咯,鬥魚4000萬元「罰單」來了,網友各種神評懟鬥魚
※你怎麼看待鬥魚tv韋神絕地求生連續直播12小時?
※我曾經被直播平台違約,主播很弱勢