通过对B站的抓包分析,可以发现有一个API是可以获取UP主的相关信息,其中就包括粉丝数量。
这个API的链接如下:
https://api.bilibili.com/x/web-interface/card?mid= UP主的uid
UP主的uid可以从UP主的空间主页链接中获取,如下图。
接下来,使用python的request模块来获取这个API返回的信息,如下图。我们可以从返回的信息中看到粉丝的数量以及关注的人数量。
然后,将API返回的数据转化为JSON格式的,方便后面数据的处理。这里需要导入json模块。
import requests
import json
# up主的uid
uid = 2026561407
# 获取API的数据
data = requests.get('https://api.bilibili.com/x/web-interface/card?mid='+str(uid))
# 将数据转为JSON格式
info = json.loads(data.text)
通过对上面获取的json数据的分析,可以发现:粉丝数量的位置是在data->card->fans,而UP主的名称是在data->card->name。由此我们可以筛选出我们需要的数据。
# 获取粉丝数量、昵称
fans = info['data']['card']['fans']
name = info['data']['card']['name']
print(name+" 的粉丝数量为:"+str(fans))
由于我们需要实时记录下粉丝数据,所以在获取粉丝数据的同时也要记录下时间,因此导入time模块,记录下时间的文本格式以及时间戳。
import requests
import json
import time
# up主的uid
uid = 2026561407
# 获取API的数据
data = requests.get('https://api.bilibili.com/x/web-interface/card?mid='+str(uid))
# 将数据转为JSON格式
info = json.loads(data.text)
# 获取粉丝数量、昵称、时间
fans = info['data']['card']['fans']
name = info['data']['card']['name']
now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
now_stamp = time.time()
print(str(now)+name+" 的粉丝数量为:"+str(fans))
此处,通过pandas模块将数据构建为DataFrame格式,再转化为csv格式进行保存。保存时,使用os模块判断数据文件是否已经存在,如果存在,则数据直接追加上去,不保存表头;如果不存在,则to_csv()函数会自动创建文件,而我们则需要给他一个表头。
# 将数据写入csv文件
data = pd.DataFrame({
"time": [now], "timestamp": [now_stamp], "name": [name], "fans": [fans]})
if os.path.isfile('fans_data.csv'):
data.to_csv('fans_data.csv', mode='a', encoding='utf_8_sig', index=False, header=False)
else:
data.to_csv('fans_data.csv', mode='a', encoding='utf_8_sig', index=False)
以上代码中,os.path.isfile()是判断当前文件夹中是否存在该名称的文件;而to_csv()函数则是将DataFrame格式转为csv文件保存,其中参数mode='a’表示追加模式,index=False表示不保存索引,header=False表示不保存DataFrame格式中的表头,index和header默认为True。
完成了这些代码,最后我们只要把脚本放到服务器(或者你的电脑可以24小时运行也OK)配置运行,就可以实现实时记录UP主的粉丝数量。
如果我们希望关注的UP主粉丝到达一定数量时,可以给我们发个消息提醒,那就可以使用Python的SMTP邮件发送功能。下面以QQ邮箱的使用为例,实现发送粉丝数量邮件提醒功能,其他的邮箱也类似,要注意其SMTP端口和地址。
使用SMTP服务的前提是该邮箱要开启SMTP服务,具体操作可以查看QQ邮箱的官方说明QQ邮箱帮助中心。从官方的说明可以了解到,SMTP的地址为smtp.qq.com,端口号为465或587。另外,由于QQ邮箱的安全设置,我们需要使用授权码来作为SMTP登录的密码。获取授权码可以在QQ邮箱的设置 -> 账户 -> POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务找到,点击生成授权码并复制下来。
这里我们导入email模块,并定义一个新的函数来实现发送邮件。
from email.mime.text import MIMEText
from email.utils import formataddr
def send_email(theme, text):
# SMTP的设置
mail_host = "smtp.qq.com"
mail_port = 465
mail_pass = "授权码"
# 接收和发送的邮箱
sender = "[email protected]"
receiver = "[email protected]"
try:
# 设置邮件收发信息
msg = MIMEText(text, 'plain', 'utf-8')
msg['From'] = formataddr(("sender", sender)) # 括号里的对应发件人邮箱昵称、发件人邮箱账号
msg['To'] = formataddr(("receiver", receiver)) # 括号里的对应收件人邮箱昵称、收件人邮箱账号
msg['Subject'] = theme # 邮件的主题
# 设置服务器用户信息
server = smtplib.SMTP_SSL(mail_host, mail_port)
server.login(sender, mail_pass) # 括号中对应的是发件人邮箱账号、邮箱密码
server.sendmail(sender, receiver, msg.as_string()) # 括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件对象
server.quit() # 关闭连接
print("邮件发送成功")
except smtplib.SMTPException as e:
print("邮件发送失败")
print(e)
接下来,只要在原先获取数据的代码基础上,添加上判断发送邮件的条件然后调用send_email()函数就可以了。在这里,我设置发送邮件提醒的条件是每增加一万粉丝就提醒。
# 判断是否需要进行邮件提醒
last_data = pd.read_csv("fans_data.csv")
last_fans = last_data.iloc[-1]["fans"] # 读取上一次的粉丝数量记录
a = int(fans/10000)
b = int(last_fans/10000)
if a - b > 0:
theme = "冰冰的B站粉丝突破"+str(a)+"万啦!!!"
text = "祝贺" + theme + "\r\n" + name + " 现在的粉丝有:" + str(fans)
send_email(theme, text)
绘制图像当然是用数据可视化最常用的工具matplotlib,具体使用可以参照网上其中的文章,非常多,这里我就是来个简单的绘制粉丝数量-时间的折线图。
import matplotlib.pyplot as plt
df = pd.read_csv("fans_data.csv")
df.plot(x='time', y='fans', figsize=(14, 5), title="Curve: The Bilibili fans number of Wang Bingbing")
plt.show()