æäºåç¯æç« ãæ³æ¾æè¦é è¢ï¼KOLï¼ä¾åçè¡é·åï¼è¶ ç´è§æé¸ â ãæ¦å¿µç¯ããçæ¦å¿µå¾ï¼æåå¯ä»¥æå¾æ¸æçè§åº¦ä¾æé¸é©åçKOLãç¾å¨ææ¸ååKOLæ´»èºå¨Youtubeå½±é³å¹³å°ï¼è©²å¦ä½åé¸æå¢ï¼å¨Influencer網ç«ä¸ï¼å¹«æåæ´çäºæ¯åKOLçé¡å¥ãç²çµ²æ¸éãå¹³åè§çæ¸éãNoxè©åã
éç¶æéäºè³æï¼ä½éæ¯ä¸ç¥éå¦ä½é¸æKOLåï¼ æè¦é è¢åæåçX軸çºãå¹³åè§ç次æ¸ãï¼Y軸åçºãè¨é±æ¸éãï¼åå大å°çºãNoxè©åãï¼èç·çºå¹³åå¼ï¼è³æä¸æ¨£ä¾èªæ¼Influencer幫æåæ´ç好çè³æãé樣åç¾è³ææä»éº¼æ義å¢ï¼
åå å¨æ¼ï¼KOLçåä½éé¡é常浮åï¼è大å¤é½èãè¨é±æ¸éãææ£æ¯ï¼ä½è¥å®çãè¨é±æ¸éãï¼æç¼ç¾è¤è²çåé»ï¼ç¬¬äºè±¡éï¼è¨é±æ¸é常é«ï¼ä½å¹³åè§ç次æ¸å»ä¸ç¡çæ³ï¼è¥ççè¦è該KOLåä½ï¼è±ä¸æ¯ãé·è²å¤§é¨é»å°ãã
ç¸å°çç¶ è²çåé»ï¼ç¬¬å象éï¼æ£å¥½ç¸åï¼éç¶è¨é±æ¸ä¸å¦å ¶ä»KOLï¼ä½æ¯é¨å½±çé½æä¸é¯çæå ï¼KOLçç²çµ²é»æ¿åº¦å¾é«ãç¶ç¶ï¼è¥æ¨çåçé ç®ä¸ä½ï¼éæ¯å¯ä»¥é¸æç´ è²çåé»ï¼ç¬¬ä¸è±¡éï¼ï¼è½æè¼é«çæåè¡é·æ©çã
ç¬è²çéé»å¨æ¼ãè³æå¾åªä¾ï¼ãï¼ç¬¬ä¸åæç´è§çæ¹å¼ï¼å°±æ¯ç´æ¥å¨ç®ç網é ä¸æä¸F12ï¼ä¹ç確å¨Network â > Doc裡é¢ç¼ç¾ä¸åå°å ï¼ææ´å網é çç¨å¼ç¢¼ï¼ç¶ç¶å å«æåæ³è¦çè³æã
ä½ç¶æåå¾ä¸æ»¾ï¼æç¼ç¾åªæ50çè³æï¼è網ç«æåè¼å ¥å¦å¤50çè³æï¼ç±æ¤å¯ç¥ï¼è¥æåç´æ¥ç¨getè«æ±çæ¹å¼æåè³æï¼å°±åªè½æåtop50ï¼å¦ä½è½æå°æ´å¤è³æå¢ï¼
å¾ä¸æ»¾åæç¼ç¾ï¼å¨åé¡XHRä¸å¤äºä¸åæ°çå°å ï¼æ¥çå §å®¹æç¼ç¾ï¼æ¯ç¬¬51ï½100ççè³æï¼èä¸é¤äºéäºè³æï¼æ²æå ¶ä»éè¨ã
確å®æåè¦çå°å å¾ï¼å°±å¯ä»¥åæå°Headersè¤è£½è©²ç¶²åã詳細ç解è®éå網åå¯ä»¥ç¼ç¾ï¼ç¶²åæå¾æ¹çåæ¸pageNumå¯è½å°±æ¯ï¼æ±ºå®ã第幾é çè³æãã
https://tw.noxinfluencer.com/youtube-channel-rank/_influencer-rank?country=tw&category=all&rankSize=100&type=0&interval=weekly&pageNum=2
æ¥ä¸ä¾å©ç¨bs4å¥ä»¶è«æ±ï¼ä¾ç §æ¯åè³æçclass屬æ§ï¼å³å¯æä¸ååyoutuberçè³æãè¥æ¨ä¸ç¥éçºä»éº¼è¦ç¨ãkol-nameãããcategory-textãããfollowerNumãâ¦ï¼æ¨å¯ä»¥åèãPythonç¬ä¸PTTæç« å §å®¹æå·§(å«ç¨å¼ç¢¼)ãï¼è£é ææ詳ç¡ææç解說ã
è«æ±ç¶²ç«
list_req = requests.get(url)
å°æ´å網ç«çç¨å¼ç¢¼ç¬ä¸ä¾
soup = BeautifulSoup(list_req.content, "html.parser")
æ¾å°æ¨ç±¤
getAllName = soup.findAll('span',{'class','kol-name'})
getAllClass = soup.findAll('a',{'class','category-text'})
getAllFans = soup.findAll('td',{'class','followerNum'})
getAllLooked = soup.findAll('td',{'class','avgView'})
getAllStar = soup.findAll('td',{'class','nox-score'})
主è¦æ¯å°æ¯åè³æåéå¥é¡å°æ¾å°ä¸åçé£åï¼æ¹ä¾¿ççè½ä¹DataFrameçæ ¼å¼ãå ¶ä¸è¦æ³¨æï¼å¨è³æä¸æ許å¤ç空ç½ï¼å æ¤å¿ é 使ç¨replaceæ¹æ³ï¼å°ç©ºç½çµ¦å»é¤ã
#éå§æ´çè³æ
theName = []
theClass = []
theFans = []
theLooked = []
theStar = []
for i in range(50):#æ¯ä¸é åªæäºåçè³æ
theName.append(getAllName[i].text)
theClass.append(getAllClass[i].text.replace(' ',''))
theFans.append(getAllFans[i].find('span').text.replace(' ','')[:-1])
theLooked.append(getAllLooked[i].find('span').text.replace(' ','')[:-1])
theStar.append(getAllStar[i]['data-score'])
data = pd.DataFrame({
'Youtuberå稱':theName,
'é »éåé¡':theClass,
'è¨é±æ¸é':theFans,
'å¹³åè§ç次æ¸':theLooked,
'Noxè©ç´':theStar
})
container = pd.concat([container,data])
time.sleep(3)
æ¥èå°ææçæ¸å¼è³æé²è¡è½æï¼å¦åé è¨é½æ¯é¡å¥åè³æï¼ä¸ä¾¿æ¼æ¸å¸éç®ã
container['è¨é±æ¸é'] = container['è¨é±æ¸é'].astype(float)
container['å¹³åè§ç次æ¸'] = container['å¹³åè§ç次æ¸'].astype(float)container['Noxè©ç´'] = container['Noxè©ç´'].astype(float)
æ¨ä¹å¯ä»¥å°æ´çå®çè³æï¼å©ç¨Pandaså¥ä»¶ä¸çæ¹æ³to_csv()é²è¡å²åã注æå¿ é è¨å®ç·¨ç¢¼çºutf-8-sigï¼å¦åå²åçè³æææ¯äºç¢¼ãå¦å¤Index=Falseè½è®çµæè³æä¸è¦æindexï¼å¦æ¤ä¸ä¾è³æçèµ·ä¾å°±ä¸æé£éº¼éäºäºã
container.to_csv('å°ç£youtuberæå.csv', encoding='utf-8-sig', index=False)
é¦å ï¼è¦æ±ºå®çæ¯ï¼åå象éè¦åå¥çµ¦äºä¸åçé¡è²ï¼ä¸åªäºé»è¦é¡¯ç¤ºYoutuberçå稱ãå¨ç¯ä¾ä¸æ¯åªæ顯示第ä¸è±¡éçYoutuberå稱ï¼åå å¨æ¼å ¶ä»ååçé»å¤ªéæ¼å¯éï¼å æ¤é¡¯ç¤ºç話æçèµ·ä¾é常éäºã
é²è¡è³æåæ
plt.figure(figsize=(20,10))
colorlist = []
for tx,ty,ab in zip(container['è¨é±æ¸é'],container['å¹³åè§ç次æ¸'], container['Youtuberå稱']):
Aavg = container['è¨é±æ¸é'].mean()
Bavg = container['å¹³åè§ç次æ¸'].mean()
if (tx < Aavg) & (ty < Bavg):#第ä¸è±¡é
colorlist.append('#abc4d8')
elif (tx > Aavg) & (ty < Bavg):
colorlist.append('#abd8bf')
elif (tx < Aavg) & (ty > Bavg):
colorlist.append('#d8bfab')
else:
plt.text(tx,ty,ab, fontsize=15)# å ä¸æå註解
colorlist.append('#d8abc4')
æ¨å¯è½ææçåçå°æ¹æ該æ¯såæ¸ï¼såæ¸æ§å¶çäºååç大å°ï¼èå¨ç¯ä¾ä¸æåå©ç¨ãNoxè©ç´ãçè³æä½çºä¾æãçºä½å°è³æ3次æ¹åä¹ä¸50å¢ï¼åå å¨æ¼è®ååç大å°å·®è·è®å¤§ï¼åè¨å ©åæ¸å¼[3, 5]ï¼å ©è ç¸è·2ï¼ç¶é3次æ¹å¾æè®æ[27, 125]ï¼å ©è ç¸è·è®æ98ï¼æ´è½å¼·èª¿å ©è çå·®ç°ã
#繪製åé»
plt.scatter(container['è¨é±æ¸é'],container['å¹³åè§ç次æ¸'],
color= colorlist,
s=container['Noxè©ç´']*350,
alpha=0.5)
繪製åç´ç·èæ°´å¹³ç·åå¥æ¯ä½¿ç¨axvline()èaxhline()æ¹æ³ï¼linestyleåæ¸æ±ºå®ç·ç樣å¼ï¼èlinewidth決å®ç·ç寬度ã
plt.axvline(container['è¨é±æ¸é'].mean(), color='c', linestyle='dashed', linewidth=1) # 繪製平åç·
plt.axhline(container['å¹³åè§ç次æ¸'].mean(), color='c', linestyle='dashed', linewidth=1) # 繪製平åç·
æå¾å°çµæåçç¢åºï¼é裡æ¨å¯ä»¥é¸æææå¾ä¸è¡savefig()æ¹æ³ç註解æ¿æï¼ä¾¿å¯ä»¥å°åçèªååæªã
plt.title("æè¦é è¢åæ",fontsize=30)#æ¨é¡
plt.ylabel('è¨é±æ¸é',fontsize=20)#yçæ¨é¡
plt.xlabel('å¹³åè§ç次æ¸',fontsize=20) #xçæ¨é¡
plt.tight_layout()
# plt.savefig('æè¦é è¢åæ.png', dpi=300)
作者:楊超霆 行銷搬進大程式 創辦人