Python數據抓取與可視化實戰——網易雲課堂人工智慧與大數據板塊課程實戰

本篇內容數據抓取對象為網易雲課堂人工智慧與大數據板塊課程信息,使用的工具是urllib+postman,因為直接構建的POST抓取的josn數據包,所以數據抓取的代碼非常簡單,沒有繁雜的xpath或者css表達式。可視化部分使用matplotlib,感謝劉順祥大神的matplotlib教程系列,讓我沒怎麼費力氣就直接復用了大量代碼!

mp.weixin.qq.com/s/E_r5

以下是數據抓取部分代碼:

import json,timefrom urllib.request import urlopen,Requestheaders = { "content-type":"application/json", ###這裡要特別注意,edu-script-token參數是一個變動從參數, ###每請求一次都會變動,所以這裡的代碼需要你使用自己在網易雲課堂後台找到 ###請求的edu-script-token參數,否則直接運行此代碼是無法出結果的 "edu-script-token":"efb08e512fdc4c5e92346f2aed124144", "Host":"study.163.com", "Origin":"http://study.163.com", "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36" }Payloads={ "pageIndex":1, "pageSize":50, "relativeOffset":0, "frontCategoryId":"400000000158033", "searchTimeType":-1, "orderType":0, "priceType":-1, "activityId":0 }url="http://study.163.com/p/search/studycourse.json"def GetCourses(url,header=headers,Payload=Payloads): fullinfo=[] for i in range(1,17): Payload["pageIndex"]=i Payload["relativeOffset"]=50*i-50 content=Request(url,data=json.dumps(Payload).encode(encoding="utf-8"),headers=header) response=json.loads(urlopen(content).read().decode("UTF-8")) fullinfo=fullinfo+response["result"]["list"] print("第{}頁已抓取完畢".format(i)) time.sleep(1) print("all page is OK!!!") return fullinfo#運行程序:mydata=GetCourses(url)#轉換為數據框myresult=pd.DataFrame(mydata)#查看變數信息:myresult.info()myresult=myresult.astype({"courseId":"str"})#刪除數據缺失列nouse=["bigImgUrl","activityIds","gmtModified","published","schoolShortName","tagIap","tagLectorTime","courseCardProps","displayType","endTime","imgUrl","productId","startTime"]myresult=myresult.drop(nouse, axis=1)myresult.head(10) #預覽數據myresult=myresult.set_index("courseId")myresult.to_csv("D:/Python/Data/yunketang_ai_bigdata.csv")

以下是使用Chome+postman進行POST請求構建的過程:

以上是本次爬取數據表,按照這些欄位屬性,之前曾經做過一期網易雲課堂Excel模塊課程抓取與可視化的推送。因為雲課堂的課程信息欄位基本一致,本次分析仍然 按照那個思路進行。

結合我個人的需求以及雲課堂的課程評價體系,我將本次分析的目標及思路梳理如下:

課程來源分析

  • 課程來源
  • 作者貢獻數

課程內容分析

  • 高頻技能需求

課程價格分析

  • 課程價格分析

課程知名度分析

  • 用戶數分析

課程口碑分析

  • 評分分析

根據以上幾個模塊,我們開始今天的可視化分析之旅!

1、課程來源分析:

雲課堂人工智慧與大數據模塊一共有791門有效課程,課程欄位中提供了機構信息和教師信息,倘若機構信息與教師信息一致,那麼基本可以認為課程是個人名義發布的,否則則是以機構名義發布的。(不一定客觀,本次以代碼練習為主)。

myresult.columnssum(myresult.lectorName==myresult.provider)/len(myresult)0.34639696586599239import matplotlib.pyplot as plt%matplotlib inlineplt.style.use("classic") labels = ["個人","機構"] colors=["#2D6D66","#008BBC"] plt.figure(figsize=(8,6),facecolor="#ebebeb") plt.rcParams["font.sans-serif"] = ["Microsoft YaHei"] plt.rcParams["axes.unicode_minus"] = Falseplt.axes(aspect="equal",facecolor="#ebebeb") ax =plt.gca()ax.spines["left"].set_visible(False)ax.spines["right"].set_visible(False) ax.spines["top"].set_visible(False) ax.spines["bottom"].set_visible(False) plt.xlim(0,4) plt.ylim(0,4)# 繪製餅圖plt.pie(percent, labels=labels, colors=colors, autopct="%.1f%%", pctdistance=0.8, labeldistance = 1.15, startangle = 90, radius = 1.5, counterclock = False, wedgeprops = {"linewidth": 0.5,"edgecolor":"white"}, textprops = {"fontsize":14,"color":"k"}, center = (1.8,1.8), frame = 1 ) plt.xticks(()) plt.yticks(())plt.title("雲課堂人工智慧與大數據模塊課程來源性質分布",fontdict={"fontsize":16},loc="left")plt.show()

從餅圖可以很明顯的看到,個人發布的課程佔據整個課程模塊課程總量的約35%,而機構則佔了大多數,搞到65%,還記得我們上次分析Excel板塊課程的時候得到的結論嗎,Excel板塊的課程中個人發布的課程量高達63%,而人工智慧大數據板塊則是機構的天下。個人覺得人工智慧與大數據行業是一個高門檻、高技術行業,所需要的條件和依賴的資源都不是個人可以負擔的,所以這個行業的課程基本都是機構或者團隊化運作。

作者貢獻數:

import squarifyimport randomcount=myresult["provider"].value_counts()count=count.sort_values(ascending=False)以下通過樹狀圖來呈現那些發布課程頻率(數量)比較處於前列的機構或者個人。plt.style.use("classic") plt.rcParams["font.sans-serif"] = "Microsoft YaHei"plt.rcParams["axes.unicode_minus"] = Falseplt.figure(figsize=(13,10),facecolor="#ebebeb") colors = ["#6794a7","#014d64","#76c0c1","#01a2d9","#7ad2f6","#00887d"]plot = squarify.plot(sizes =count[count>5].values , label = list(count[count>10].index)+[""]*27, color = random.choices(colors,k=len(count[count>5])), alpha = 0.6, value = list(count[count>10].values)+[""]*27, edgecolor = "white", linewidth =1 ) plot.set_title("雲課堂人工智慧與大數據課程發布來源統計",fontdict = {"fontsize":18},loc="left") plt.axis("off") plt.tick_params(top = "off", right = "off") plt.show()

我篩選了發布課程的前十名,並用條形圖來進行呈現。

plt.style.use("classic")plt.rcParams["font.sans-serif"] =["Microsoft YaHei"]plt.rcParams["axes.unicode_minus"] = Falseplt.figure(figsize=(10,6),facecolor="#ebebeb")plt.barh(range(9,-1,-1),count.values[:10], align = "center",color=random.choices(colors), alpha = 0.8)plt.xlim(1,55)plt.yticks(range(9,-1,-1),count.index[:10])plt.xlabel("課程發布數")plt.title("雲課堂人工智慧與大數據課程模塊發布量TOP10統計",fontdict = {"fontsize":18},loc="left")ax =plt.gca()ax.spines["left"].set_visible(False)ax.spines["right"].set_visible(False) ax.spines["top"].set_visible(False) ax.spines["bottom"].set_visible(False) ax.grid(axis= "x",which= "major",linestylex="dashed",color="grey") for x,y in zip(range(9,-1,-1),count.values[:10]): plt.text(y+0.2,x,"%s" %y,va="center")plt.show()

通過以上樹狀圖和條形圖的數據呈現,我們可以很清晰的看到,小蚊子團隊居然在人工智慧和大數據板塊一共發布了51門課程,要知道這個模塊一共只有791門有效課程,這可是足足佔了總課程量的51/791=6.5%啊我天,著實是高產至極,記得最初學習數據分析的時候,就層看過張聞霖老師的誰說菜鳥不會數據分析系列,為老師的高產點贊!!!

這個條形圖可以看出發布課程數在10門以上的top10作者,基本呈現三級梯隊分布,各梯隊間距10門左右,小蚊子數據分析基本佔據第一梯隊,出於第二梯隊的是普開數據檸檬學院和經管之家CDA數據分析研究院,分別發布了40、39門課程。而第三梯隊課程發布數基本在30門以下,除了唐宇迪老師發布了26門,SAP中國渠道雲學院發布了20門之外,其他均不足20門。鑒於人工智慧與大數據行業的高門檻性,依然能以這麼高頻率發布課程,當然是只有團隊運作才能支撐的起如此的資源和高強度課程量,這樣印證了我們上文說過的,機構作者與個人作者的分布比例。

count2=myresult["provider"].value_counts()plt.style.use("classic") plt.rcParams["font.sans-serif"] = "Microsoft YaHei"plt.rcParams["axes.unicode_minus"] = Falsefig = plt.figure(figsize=(10,6),facecolor="#ebebeb")plt.plot(range(0,219), count2.cumsum(), linestyle = "-", linewidth = 2, color = "#2D6D66", marker = "o", markersize = 4, markeredgecolor="white", markerfacecolor="#C10534" ) plt.title("人工智慧與大數據課程累計發布頻率分布") plt.xlabel("作者累計數(按照發布課程數量排序)") plt.ylabel("課程發布頻數") ax =plt.gca()ax.spines["left"].set_visible(False)ax.spines["right"].set_visible(False) ax.spines["top"].set_visible(False) ax.spines["bottom"].set_visible(False) ax.grid(axis= "x",which= "major",linestylex="dashed",color="grey") plt.xlim(-1,225)plt.yticks(range(0,800,100),range(0,800,100))plt.tick_params(top = "off",right="off") plt.show()

以上我將所有課程作者按照發布課程頻數做了累計分布呈現,可以看到前50個作者的課程貢獻數已經累計達到了500門以上,而之後分布曲線已經大幅走緩,最後坡度已經接近直線,說明該板塊的課程主要集中在那些少數機構手中,特別是前50名作者發布了超過500門課程,也即25%的作者掌握著70%以上的課程資源,可見該模塊課程的壟斷程度。

2、課程內容分析:

import jiebafrom wordcloud import WordCloud, STOPWORDS, ImageColorGenerator import matplotlib.pyplot as pltimport numpy as np

課程標題分詞高頻辭彙統計

word_list = [" ".join(jieba.cut(sentence)) for sentence in myresult["productName"]]new_text = " ".join(word_list) wc= WordCloud( background_color="white", max_words=2000, stopwords=STOPWORDS.add("said"), max_font_size=80, font_path = "msyh.ttf", random_state=42 ) wordcloud =wc.generate(new_text)fig = plt.figure(figsize=(10,8),facecolor="#ebebeb")plt.imshow(wordcloud,interpolation="bilinear")plt.axis("off")plt.show()

課程描述高頻辭彙統計

word_list = [" ".join(jieba.cut(sentence)) for sentence in myresult["description"] if sentence!=None]new_text = " ".join(word_list) new_text=new_text.replace("
","")wc= WordCloud( background_color="white", max_words=2000, stopwords=STOPWORDS.add("said"), max_font_size=80, font_path = "msyh.ttf", random_state=42 ) wordcloud =wc.generate(new_text)fig = plt.figure(figsize=(10,8),facecolor="#ebebeb")plt.imshow(wordcloud,interpolation="bilinear")plt.title("人工智慧與大數據課程描述高頻詞統計")plt.axis("off")plt.show()

從課程名稱以及課程描述的分詞統計來看,該模塊的標題還是側重與基礎、入門、實戰、應用等較低層次的需要需求,而對於機器學習、深度學習、演算法、構架等較為深入的層面詞頻分布較少,這也從側面可以看出,網易雲課堂的大數據與人工智慧模塊課程更側重數據科學的入門、通識級別學習資源。(由於手頭沒有合適的關於數據科學領域的停止詞,所以沒有使用停止詞,函數中那個停止詞是英文的,只能清楚一些特殊符號和標點,所以課程描述的分詞結果並不理想)。

3、課程價格分析

本來對於課程來講,價格分析是極具價值的課程信息,但是遺憾的是,折扣價缺失過於嚴重,這裡我用原價進行分析(儘管原始價格可能不能反映課程質量)。

price_data1=myresult.loc[myresult["originalPrice"]!=0,["lectorName","originalPrice","productName","learnerCount","score"]].sort_values(by="originalPrice",ascending=False)len(price_data1)/len(myresult);len(price_data1)0.6662452591656132527

從原始價格來看,一共有527門付費課程,總體付費課程佔比66.7%。但是對於在線課程而言,單純高價而沒有用戶(或者用戶極少),或者完全為了給其他平台引流而免費,都不能真正體現出課程的價值。

price_data1.iloc[:10]

價格前十位的用戶數可以看出,除了第二個課程外,這些價格虛高的課程很少有人問津,或者換句話說,網易雲課堂本就不是一個人工智慧與大數據深度課程資源集聚地,多數課程以入門或者通識為主,而學習者的對於高價課程的付費意願也不高,這到底是因為雲課堂的平台性質決定了內容深度,還是用戶群體的需求性質與付費意願決定了課程內容與深度,這一點很難講。

我剔除掉10元以下、1000元以上的課程,希望這樣可以使得結果相對客觀一些!

course1000=price_data1.loc[(price_data1.originalPrice>=10) &(price_data1.originalPrice<=1000),]len(price_data1.loc[price_data1.originalPrice<10,])len(price_data1.loc[price_data1.originalPrice>1000,])len(course1000)62 10 455course1000new=course1000.groupby("lectorName")["originalPrice"].mean()course1000new=course1000new.sort_values(ascending=False)[:10]plt.style.use("classic") plt.rcParams["font.sans-serif"] = "Microsoft YaHei"plt.rcParams["axes.unicode_minus"] = Falsefig = plt.figure(figsize=(10,8),facecolor="#ebebeb")plt.bar(range(10),course1000new.values,align = "center",color=random.choices(colors), alpha = 0.8)ax =plt.gca()ax.spines["left"].set_visible(False)ax.spines["right"].set_visible(False) ax.spines["top"].set_visible(False) ax.spines["bottom"].set_visible(False) ax.grid(axis= "y",which= "major",linestylex="dashed",color="grey") plt.ylabel("課程平均價格")plt.title("人工智慧與大數據課程平均價格分析",fontdict = {"fontsize":18},loc="left")plt.xticks(range(10),course1000new.index)plt.ylim(0,1000)for x,y in enumerate(course1000new.values): plt.text(x,y+10,"%s" % y,ha="center")plt.show()

從課程平均價格來看,卡夫卡大數據、張耀軍、易丹輝價格佔據前三甲,分別為999、980、其他課程作者價格均在900以下。

4、課程用戶分析:

用於用戶數與課程是否收費有極大的關係,所以付費課程與免費課程放在一起分析用戶數是不合理的。

learn_data=myresult.loc[:,["provider","originalPrice","learnerCount","score","productName"]]princeno=learn_data.loc[learn_data.originalPrice!=0,["productName","provider","originalPrice","learnerCount"]].sort_values (by="learnerCount",ascending=False)import matplotlib.pyplot as pltimport random%matplotlib inlinecolors = ["#6794a7","#014d64","#76c0c1","#01a2d9","#7ad2f6","#00887d"]plt.style.use("classic")plt.rcParams["font.sans-serif"] =["Microsoft YaHei"]plt.rcParams["axes.unicode_minus"] = Falseplt.figure(figsize=(10,6),facecolor="#ebebeb")plt.barh(range(9,-1,-1),princeno.learnerCount[:10], align = "center",color=random.choices(colors), alpha = 0.8)plt.xlim(1,2500)plt.yticks(range(9,-1,-1),princeno.productName[:10])plt.tick_params(top = "off",right="off",bottom="off",left="off") plt.xlabel("學員數量")plt.title("雲課堂人工智慧與大數據課程模塊付費課程學院人數TOP10統計",fontdict = {"fontsize":18},loc="left")ax =plt.gca()ax.spines["left"].set_visible(False)ax.spines["right"].set_visible(False) ax.spines["top"].set_visible(False) ax.spines["bottom"].set_visible(False) ax.grid(axis= "x",which= "major",linestylex="dashed",color="grey") for x,y in zip(range(9,-1,-1),princeno.learnerCount[:10]): plt.text(y+2,x,"%s" %y,va="center")plt.show()

付費課程中,最高量級的學院數量課程為SQL數據分析實踐,學員數有2000+,值得注意的是,top10課程中竟然有四門涉及Python或者爬蟲實戰課程,可見大家對於爬蟲需求量是多麼旺盛。

princeyes=learn_data.loc[learn_data.originalPrice==0,["productName","provider","originalPrice","learnerCount"]].sort_values (by="learnerCount",ascending=False)plt.style.use("classic")plt.rcParams["font.sans-serif"] =["Microsoft YaHei"]plt.rcParams["axes.unicode_minus"] = Falseplt.figure(figsize=(10,6),facecolor="#ebebeb")plt.barh(range(9,-1,-1),princeyes.learnerCount[:10], align = "center",color=random.choices(colors), alpha = 0.8)plt.xlim(1,140000)plt.yticks(range(9,-1,-1),princeyes.productName[:10])plt.tick_params(top = "off",right="off",bottom="off",left="off") plt.xlabel("學員數量")plt.title("雲課堂人工智慧與大數據課程模塊免費課程學院人數TOP10統計",fontdict = {"fontsize":18},loc="left")ax =plt.gca()ax.spines["left"].set_visible(False)ax.spines["right"].set_visible(False) ax.spines["top"].set_visible(False) ax.spines["bottom"].set_visible(False) ax.grid(axis= "x",which= "major",linestylex="dashed",color="grey") for x,y in zip(range(9,-1,-1),princeyes.learnerCount[:10]): plt.text(y+20,x,"%s" %y,va="center")plt.show()

而反觀免費課程模塊,最具人氣的是數據結構與演算法,竟然達到了126000+的學院數量,第二名是MySQL資料庫,用戶量達到了83590,之後的8門用戶量均在60000以下。有趣的是,免費課程的用戶量top10中,竟然有4門資料庫相關,可見資料庫技能在數據科學中地位與重要性以及普及程度。

但是付費課程與免費課程的用戶量級差異極大,基本都在10倍數量差以上,由此可見付絕大多數用戶對於價格還是敏感的。

5、用戶評分分析:

因為評分是5分制的,而且只能精確到一位小數,所以這裡我使用單個作者所有課程的累計評分和來進行簡要分析(因為累計評分跟課程數量有關,計算總評分量可能不夠客觀,這裡僅用作綜合人氣的替代指標,因為平均評分會出現大量相同的評分)。

scoreno=learn_data.loc[learn_data.originalPrice==0,].groupby("provider")["score"].sum().sort_values(ascending=False)plt.style.use("classic")plt.rcParams["font.sans-serif"] =["Microsoft YaHei"]plt.rcParams["axes.unicode_minus"] = Falseplt.figure(figsize=(10,6),facecolor="#ebebeb")plt.barh(range(9,-1,-1),scoreno.values[:10], align = "center",color=random.choices(colors), alpha = 0.8)plt.xlim(1,250)plt.yticks(range(9,-1,-1),scoreno.index[:10])plt.tick_params(top = "off",right="off",bottom="off",left="off") plt.xlabel("累計評分")plt.title("雲課堂人工智慧與大數據課程模塊免費課程累計評分TOP10統計",fontdict = {"fontsize":18},loc="left")ax =plt.gca()ax.spines["left"].set_visible(False)ax.spines["right"].set_visible(False) ax.spines["top"].set_visible(False) ax.spines["bottom"].set_visible(False) ax.grid(axis= "x",which= "major",linestylex="dashed",color="grey") for x,y in zip(range(9,-1,-1),scoreno.values[:10]): plt.text(y+0.2,x,"%s" %y,va="center")plt.show()scoreyes=learn_data.loc[learn_data.originalPrice!=0,].groupby("provider")["score"].sum().sort_values(ascending=False)plt.style.use("classic")plt.rcParams["font.sans-serif"] =["Microsoft YaHei"]plt.rcParams["axes.unicode_minus"] = Falseplt.figure(figsize=(10,6),facecolor="#ebebeb")plt.barh(range(9,-1,-1),scoreyes.values[:10], align = "center",color=random.choices(colors), alpha = 0.8)plt.xlim(1,250)plt.yticks(range(9,-1,-1),scoreyes.index[:10])plt.tick_params(top = "off",right="off",bottom="off",left="off") plt.xlabel("累計評分")plt.title("雲課堂人工智慧與大數據課程模塊免付費程累計評分TOP10統計",fontdict = {"fontsize":18},loc="left")ax =plt.gca()ax.spines["left"].set_visible(False)ax.spines["right"].set_visible(False) ax.spines["top"].set_visible(False) ax.spines["bottom"].set_visible(False) ax.grid(axis= "x",which= "major",linestylex="dashed",color="grey")for x,y in zip(range(9,-1,-1),scoreyes.values[:10]): plt.text(y+0.2,x,"%s" %y,va="center")plt.show()

從免費與付費課程發布作者的累計評分綜總數來看,小蚊子數據分析都奪得頭籌,可見小蚊子老師是在免費和付費課程上都貢獻了絕對多數的課程量,兩線發力,因而坐擁龐大的用戶群體。

有意思的是,在top10免費課程機構和付費課程機構累計評分top10榜單中,竟然有七席課程一直保持在榜單內,前四席課程的排序並未易主,說明這些大機構團隊基本都是是雙線發力,在開發付費課程的同時,也兼顧免費課程的蓄力,進而交叉引流,開拓用戶群體。

coursename=list(set(scoreno.index[:10,]).intersection(set(scoreyes.index[:10,])))princeno=learn_data.loc[(learn_data["provider"].isin(coursename)) & (learn_data["originalPrice"]==0),"provider"].value_counts()princeyes=learn_data.loc[(learn_data["provider"].isin(coursename)) & (learn_data["originalPrice"]!=0),"provider"].value_counts()princeresult = pd.concat([princeno,princeyes], axis=1)princeresult=princeresult.rename(index=str, columns={"provider":"priceno", "provider":"priceyes"})plt.style.use("classic")plt.rcParams["font.sans-serif"] = "Microsoft YaHei" plt.rcParams["axes.unicode_minus"] = Falsevalues = princeresult.iloc[:,0].valuesvalues2 =princeresult.iloc[:,1].valuesfeature = princeresult.indexangles=np.linspace(0, 2*np.pi,len(values), endpoint=False)values=np.concatenate((values,[values[0]]))values2=np.concatenate((values2,[values2[0]]))angles=np.concatenate((angles,[angles[0]]))fig=plt.figure(figsize=(10,8),facecolor="#ebebeb")ax = fig.add_subplot(111, polar=True)ax.plot(angles, values, "o-", linewidth_=2, label = "免費")ax.fill(angles, values, alpha=0.25)ax.plot(angles, values2, "o-", linewidth_=2, label = "付費")ax.fill(angles, values2, alpha=0.25)ax.set_thetagrids(angles * 180/np.pi, feature)ax.set_ylim(0,50)plt.title("高價值課程發布者免費與付費課程發布量",fontdict = {"fontsize":18},loc="left")ax.grid(True)plt.legend(loc = "best")plt.show()

以上雷達圖可以看到,凡是付費課程數比較多的發布機構,都會貢獻一定的免費課程資源,小蚊子數據分析和知數學院提供了相對較多的免費課程數量,但總體而言,這些大機構的付費科課程數量與免費課程數量基本相差10倍左右。

在線課程請點擊文末原文鏈接:

Hellobi Live | 9月12日 R語言可視化在商務場景中的應用

往期案例數據請移步本人GitHub:

github.com/ljtyduyu/Dat


推薦閱讀:

使用Matplotlib畫動態圖實例
matplotlib.pyplot.imshow如何顯示灰度圖?

TAG:Python | 数据可视化 | Matplotlib |