天天看點

客官,想瞅瞅鄧紫棋微網誌粉絲分布嗎,進來看看呗

作者:皖渝

源自:快學python

客官,想看看鄧紫棋微網誌粉絲分布嘛,跟俺一起逛一逛吧。

本文主要有三個地方需要逛一逛:python爬蟲,資料可視化,資料分析

一、微網誌爬蟲類型介紹

微網誌有關的爬蟲,由于根據網址的不同,可分為三種類型:

1.移動端爬取:利用selenium去模拟登入然後再去爬取,比較麻煩,但是可以根據個人需求依據關鍵詞進行指定爬取。

2.手機端爬取:網址為手機端微網誌網址,這在我之前的部落格中也有提及微網誌超話内容爬取,在此不再贅述。無需登入,利用Chrome進行抓包即可實作,而且較selenium來說,性能也是更高一點。(不過要注意設定随機睡眠時間)

3.舊版網址爬取:這是微網誌最簡化版本的網址weibo.cn(感覺回到了諾基亞的年代),界面簡單無需抓包,直接利用正則或者xpath等方式提取即可(需要拿到登入後的cookie值)

建議:如果隻是爬取指定使用者的評論、基本資訊這些,後兩種方法就夠用了;如果涉及到更複雜的需求時再考慮selenium爬取

二、明星粉絲資訊爬蟲

舊版的網址,粉絲數量隻顯示了前20頁,一頁10個,總共才200個。手機端下的粉絲清單總共也隻能顯示5000個,對于5000個之後的粉絲資訊,微網誌出于隐私保護,是爬取不了。詳細的情況可參考新浪微網誌如何擷取使用者全部粉絲清單

1.微網誌使用者URL說明:舊版網址使用者首頁的URL為:

http://weibo.cn/u/使用者ID

手機端使用者首頁的URL為:

https://m.weibo.cn/u/使用者ID

以鄧紫棋為例,她的ID為1705586121,首頁如下:

客官,想瞅瞅鄧紫棋微網誌粉絲分布嗎,進來看看呗

她的粉絲資訊抓包結果如下:

客官,想瞅瞅鄧紫棋微網誌粉絲分布嗎,進來看看呗
客官,想瞅瞅鄧紫棋微網誌粉絲分布嗎,進來看看呗

這裡的使用者資訊隻有使用者的簡介(screen_name)、關注數(follow_count)、粉絲數(follow_count),對應使用者性别和地區是沒有顯示的。

是以,考慮先用手機端爬取使用者ID,再用舊版網址登入,提取資訊。(舊版網址個人資訊更全一些)

2.爬取鄧紫棋粉絲所有的user_id考慮到部分使用者可能是機器人,初步篩選條件為粉絲數大于等于20

import requests
import json
import random
import os
os.chdir('C:/Users/dell/Desktop')
import time
base_url='https://m.weibo.cn/api/container/getIndex?containerid=231051_-_fans_-_1705586121&since_id='
head=[
    "Opera/12.0(Windows NT 5.2;U;en)Presto/22.9.168 Version/12.00",
    "Opera/12.0(Windows NT 5.1;U;en)Presto/22.9.168 Version/12.00",
    "Mozilla/5.0 (Windows NT 5.1) Gecko/20100101 Firefox/14.0 Opera/12.0",
    "Opera/9.80 (Windows NT 6.1; WOW64; U; pt) Presto/2.10.229 Version/11.62",
    "Opera/9.80 (Windows NT 6.0; U; pl) Presto/2.10.229 Version/11.62",
]
header={
    'user-agent':random.choice(head)
}
with open('user_id.txt','w') as f:
    for page in range(2,251): #注意是從2開始才是使用者資訊
        try:
            url=base_url+str(page)
            r=requests.get(url,headers=header)
            data=json.loads(r.text)
            all_user=data['data']['cards'][0]['card_group']
            for user in all_user:
                fans=int(user.get('desc2').split(':')[1])
                if fans >=20:
                    f.write(str(user.get('user')['id'])+'\n')
            print('第{}頁使用者id爬取完畢'.format(page))
            time.sleep(random.randint(1,3))
        except:
            print('未爬到資料')
           

複制

爬取的部分使用者ID如下:

客官,想瞅瞅鄧紫棋微網誌粉絲分布嗎,進來看看呗

3.以舊版微網誌網址,登入後擷取cookie,如下圖所示:

客官,想瞅瞅鄧紫棋微網誌粉絲分布嗎,進來看看呗

擷取後将下述代碼中的cookie改為你自己的cookie即可

import numpy as np
import pandas as pd
import requests
from lxml import etree
import random
import time
header={'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36',
       'cookie':'你自己的cookie',
       'accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
       }
url_new='https://weibo.cn/u/'
data=[]
count=0  
def  get_id(path):
 with open(path,'r') as f:
  user_list=f.readlines()
  user_id=np.char.rstrip(user_list,'\n')
  return user_id
def gethtml(url,header):
    r=requests.get(url,headers=header)
    if r.status_code==200:
        return r.text
    else:
        print('網絡連接配接異常')
for user_id in get_id('user_id.txt'):
    try:
        url=url_new+user_id
        r_text=gethtml(url,header)
        html=etree.HTML(r_text.encode('utf-8'))
        user_name=html.xpath('//span[@class="ctt"]/text()')[0]
        inf=html.xpath('//span[@class="ctt"]/text()')[1]
        weibo_number=html.xpath('//div[@class="tip2"]/span[@class="tc"]/text()')[0].replace('微網誌','').strip('[]')
        focus_number=html.xpath('//div[@class="tip2"]/a[1]/text()')[0].replace('關注','').strip('[]')
        fan_number=html.xpath('//div[@class="tip2"]/a[2]/text()')[0].replace('粉絲','').strip('[]')
        data.append([user_name,inf,weibo_number,focus_number,fan_number])
        count+=1
        print('第{}個使用者資訊寫入完畢'.format(count))
        time.sleep(random.randint(1,2))
    except:
        print('使用者資訊不完全')
df=pd.DataFrame(data,columns=['user_id','inf','weibo_num','focus_num','fans_num'])
df.to_csv('weibo_user.csv',index=False,encoding='gb18030')
           

複制

最終爬取到粉絲數量大于等于20的使用者共10647個(多次爬取的結果),清洗後的部分資料如下:

客官,想瞅瞅鄧紫棋微網誌粉絲分布嗎,進來看看呗

三、可視化

(1) 粉絲性别占比

import matplotlib.pyplot as plt
import pandas as pd
plt.style.use('ggplot')
plt.rcParams['font.sans-serif']=['kaiti']
%config InlineBackend.figure_format='svg'
df=pd.read_csv('weibo_user.csv',encoding='gbk')
gender=pd.DataFrame(df['gender'].value_counts())
plt.pie(gender['gender'],
        labels=['女','男'],
        startangle=90,
        shadow=False,
        autopct='%1.1f%%',
        textprops={'fontsize': 13, 'color': 'w'},
        colors=['#f26d5b','#2EC4B6']
       )
plt.legend(loc='best')
plt.title('鄧紫棋粉絲性别占比')
plt.axis('equal')   
plt.tight_layout()
plt.show()
           

複制

客官,想瞅瞅鄧紫棋微網誌粉絲分布嗎,進來看看呗

從性别分布來看,女粉較男粉稍多一些

(2) 全國粉絲分布情況注意:使用的是pyecharts最新版本

from pyecharts.charts import Map
from pyecharts import options as opts
import numpy as np
df=df[~df['loc'].isin(['其他'])]
loc=pd.DataFrame(df['loc'].value_counts())
city=np.char.rstrip(list(loc.index))
map1=Map(init_opts=opts.InitOpts(width="1200px",height="800px"))
map1.set_global_opts(
    title_opts=opts.TitleOpts(title="鄧紫棋粉絲地區分布"),
    visualmap_opts=opts.VisualMapOpts(max_=1500, is_piecewise=True, #最大值由max_設定
    pieces=[
    {"max": 1500, "min": 1000, "label": ">1000", "color": "#754F44"},
    {"max": 999, "min": 600, "label": "600-999", "color": "#EC7357"},
    {"max": 599, "min": 200, "label": "200-599", "color": "#FDD692"},
    {"max": 199, "min": 1, "label": "1-199", "color": "#FBFFB9"},
    {"max": 0, "min": 0, "label": "0", "color": "#FFFFFF"},
    ], ))  #最大資料範圍,分段

map1.add("",[list(z) for z in zip(city,loc['loc'])],
maptype='china',is_roam=False,
        is_map_symbol_show=False)
map1.render('fans_loc.html')
           

複制

客官,想瞅瞅鄧紫棋微網誌粉絲分布嗎,進來看看呗

從地區分布來看,廣東粉最多(畢竟紫棋是中國香港歌手嘛),其次四川、湖北、河南、山東、江蘇、浙江等省份粉絲也較多,内陸偏遠地區粉絲分布較少如新疆、雲南、貴州等

(3) 性别與地區交叉分布情況

import seaborn as sns
df_new=df[~df['loc'].isin(['其他'])]
index=df_new.groupby('loc').count().sort_values(by='gender',ascending=False).index
plt.figure(figsize=(15,6))
sns.countplot(data=df_new,x='loc',hue='gender',order=index,palette=['#f26d5b','#2EC4B6'])
plt.xticks(rotation=90)
plt.legend(loc='upper right')
plt.title('鄧紫棋男女粉絲全國分布情況')
plt.xlabel('地區')
plt.ylabel('人數')
plt.show()
           

複制

客官,想瞅瞅鄧紫棋微網誌粉絲分布嗎,進來看看呗

男粉多于女粉的地區有:廣東、北京、江蘇、四川、上海等

女粉多于男粉的地區有:、河北、海外、遼甯、湖南等

(4) 地區與粉絲類型交叉情況對使用者粉絲量以0,100,500,1000,10000,100000為分隔點,劃分為五種類型的使用者:小透明、常駐部落客,資深部落客,微網誌紅人,微網誌大V。并與地區進行交叉作圖,如下所示

df=pd.read_csv('weibo_user.csv',encoding='gbk')
label=['小透明','常駐部落客','資深部落客','微網誌紅人','微網誌大V']
df['fans_label']=pd.cut(df['fans_num'],bins=[0,100,500,1000,10000,100000],
                        labels=label)
df_new=df[~df['loc'].isin(['其他'])]
plt.figure(figsize=(15,6))
sns.countplot(x='loc',hue='fans_label',data=df_new,palette=['#754F44','#EC7357','#FDD692',                                         
'#8FBC94','#000000'],order = df_new['loc'].value_counts().index)
plt.legend(loc='upper right',frameon=False)
plt.xticks(rotation=90)
plt.ylabel('人數')
plt.xlabel('地區')
plt.title('不同粉絲類型在全國分布情況')
plt.show()
           

複制

客官,想瞅瞅鄧紫棋微網誌粉絲分布嗎,進來看看呗

從上圖可以得出以下三條結論:1.全國地區大部分使用者的粉絲量都是低于100的

2.廣東粉不僅多,而且他們的粉絲人數也很多,具體表現為常駐部落客、資深部落客、微網誌紅人均列全國第一。

3.一千粉至一萬粉的使用者除廣東外,主要分布在海外、浙江、北京、上海等地區。其中,北京一萬粉至十萬粉(微網誌大V)的數量位居全國第一。此外,微網誌大V還分布在廣東、海外、四川、上海、湖南

(5) 使用者微網誌數、關注數、粉絲量基本情況

gender_group=df.pivot_table(aggfunc=np.mean,
                            index=df['gender'],
                           values=df[['weibo_num','focus_num','fans_num']]).round(0)

f,ax=plt.subplots(1,3,figsize=(15,6))
sns.barplot(x=gender_group.index,y=gender_group['weibo_num'],
            palette=['#f26d5b','#2EC4B6'],alpha=0.8,ax=ax[0])
ax[0].set_title('男女粉絲平均微網誌數')
ax[0].set_xlabel('性别')
ax[0].set_ylabel('平均微網誌數')

sns.barplot(x=gender_group.index,y=gender_group['focus_num'],
            palette=['#f26d5b','#2EC4B6'],alpha=0.8,ax=ax[1])
ax[1].set_title('男女粉絲平均關注數')
ax[1].set_xlabel('性别')
ax[1].set_ylabel('平均關注數')

sns.barplot(x=gender_group.index,y=gender_group['fans_num'],
            palette=['#f26d5b','#2EC4B6'],alpha=0.8,ax=ax[2])
ax[2].set_title('男女粉絲平均粉絲數')
ax[2].set_xlabel('性别')
ax[2].set_ylabel('平均粉絲數')
plt.suptitle('鄧紫棋粉絲微網誌基本資訊') #子圖添加總标題
plt.show()
           

複制

客官,想瞅瞅鄧紫棋微網誌粉絲分布嗎,進來看看呗

從餅圖可知,男女粉絲數量相差不大。但平均微網誌數、關注數都要大于男粉絲,特别是平均微網誌數大緻為男粉絲的兩倍,由此可得出結論:相比男粉絲,女粉絲在微網誌活躍度會更高(原因可能在于女粉經常轉發愛豆的動态、為愛豆打榜之類的)

(6) 微網誌數、關注量、粉絲量相關性

plt.figure(figsize=(10,6))
sns.heatmap(df[['weibo_num','focus_num','fans_num']].corr(),cmap='YlGn',annot=True)
plt.title('微網誌數、關注數、粉絲數相關熱力圖')
plt.show()
           

複制

客官,想瞅瞅鄧紫棋微網誌粉絲分布嗎,進來看看呗

相關系數的範圍在-1到1之間。越接近1,正相關性越強,越接近-1,負相關性越強。(當然這裡的相關性僅指線性相關性) 從上圖來看,基本上三者之間的相關性還是很弱的,也就微網誌數與關注數相關性相對較高一點,但僅有0.26。

結語

以上就是這篇文章的全部内容了,希望本文的内容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對小編的支援。