源自:快学python
客官,快手想瞧瞧邓紫棋微博粉丝分布嘛,刷赞跟俺一起逛一逛吧。用充刷永久会员网站皮皮虾业务
本文主要有三个地方须要逛一逛:python爬虫,微博数据可视化,粉丝数据剖析
一、链接微博爬虫类型介绍
微博有关的快手爬虫,因为按照网址的刷赞不同,可分为三种类型:
1.联通端爬取:借助selenium去模拟登陆之后再去爬取,用充比较麻烦,微博而且可以依照个人需求根据关键词进行指定爬取。粉丝
2.手机端爬取:网址为手机端微博网址,链接这在我之前的快手博客中也有提到微博超话内容爬取,在此不再赘言。刷赞刷永久会员网站皮皮虾业务无需登陆,用充借助Chrome进行抓包即可实现,但是较selenium来说,性能也是更初一点。(不过要注意设置随机睡眠时间)
3.旧版网址爬取:这是微博最简化版本的网址weibo.cn(觉得回到了摩托罗拉的年代),界面简单无需抓包,直接借助正则或则xpath等方法提取即可(须要领到登陆后的cookie值)
建议:假如只是爬取指定用户的评论、基本信息这种,后两种方式就够用了;倘若涉及到更复杂的需求时再考虑selenium爬取
二、明星粉丝信息爬虫
旧版的网址,粉丝数目只显示了前20页,一页10个,总共才200个。手机端下的粉丝列表总共也只能显示5000个,对于5000个以后的粉丝信息,微博出于隐私保护,是爬取不了。详尽的情况可参考新浪微博怎么获取用户全部粉丝列表
1.微博用户URL说明:旧版网址用户首页的URL为:用户ID手机端用户首页的URL为:用户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。
结语
以上就是这篇文章的全部内容了,希望本文的内容对你们的学习或则工作具有一定的参考学习价值,感谢你们对小编的支持。