爬取微博实时热搜数据可视化分析
如今微博实时更新速度非常快,基于它每分钟更新一次热搜的情况,每分钟爬取一次信息,查看实时热搜的变动。
from fake_useragent import UserAgent # 反爬请求头
from bs4 import BeautifulSoup # BS4爬虫
from datetime import datetime # 时间处理模块
import time # 时间模块
import csv # csv模块
import requests # 爬取数据
import schedule # 定时调度模块
import pandas as pd # 数据处理
一、爬取数据
1.1 Spider主要函数
def main():
url = 'https://s.weibo.com/top/summary?cate=realtimehot&sudaref=s.weibo.com&display=0&retcode=6102'
agents = UserAgent()
headers = {'User-Agent': agents.random}
response = requests.get(url, headers=headers) # 响应数据
top_search_dict = {} # 建立字典保存数据
soup = BeautifulSoup(response.text, 'html.parser') # 解析数据
items = soup.find_all('td', class_='td-02') # 获取微博热搜数据
for item in items:
title = item.find('a').text.strip() # 获取标题
counts = item.find_all('span')
for i in counts:
top_search_dict[title] = i.get_text() # 获取热搜量
top_search_dict['date'] = datetime.now().strftime('%Y/%m/%d %H:%M') # 获取时间
with open('weibo_search.csv', 'a', encoding='gbk', newline='') as f: # 存入csv文件
w = csv.DictWriter(f, top_search_dict.keys())
w.writeheader()
w.writerow(top_search_dict)
1.2 根据微博一分钟更新一次的状态进行爬虫
# 自动运行爬虫一分钟一次
def auto_spider(stop_time):
schedule.every(1).minutes.do(main) # 设置每分钟进行一次调度
while True:
if datetime.now().strftime('%H:%M') <= stop_time: # 设置时间点判定执行调度时长
schedule.run_pending() # 执行所有调度
time.sleep(60) # 休眠1分钟
else:
break
if __name__ == '__main__':
auto_spider(stop_time='11:08')
二、可视化
可以看到每分钟的热搜数量很多,所以我们选择Top20来看。
df = pd.read_csv('weibo_search.csv', encoding='gbk', header=None)
df.loc[0,:][:20]
2.1 利用轮播图加柱状图进行可视化
from pyecharts.charts import Bar, Timeline, Grid # Bar和时间轴模块
from pyecharts.globals import ThemeType # 图片背景模块
import pyecharts.options as opts # 配置项
def draw_timeline():
df = pd.read_csv('weibo_search.csv', encoding='gbk', header=None)
# 时间轴
t = Timeline(
init_opts=opts.InitOpts(width='1024px', height='600px', theme=ThemeType.MACARONS)
)
for i in range(len(df)):
if i % 2 == 0: # 根据读取文件格式进行索引判断
bar = (
Bar(
init_opts=opts.InitOpts(width='500px', height='600px')
)
.add_xaxis(list(df.loc[i, :][:20][::-1])) # 配置x轴数据
.add_yaxis(
'微博热度', # y轴数据标题
list(df.loc[i + 1, :][:20][::-1]) # y轴数据
)
.set_global_opts(
title_opts=opts.TitleOpts(
title=df.loc[i + 1, 50], # 设置标题为时间点
pos_right='5%', # 标题位置
pos_bottom='15%',
# 标题字体配置
title_textstyle_opts=opts.TextStyleOpts(
font_family='KaiTi', # 字体格式
font_size=24, # 字体大小
color='#14d8ff' # 字体颜色
)
),
xaxis_opts=opts.AxisOpts(
splitline_opts=opts.LineStyleOpts(is_show=True, opacity=1), # x轴分割线配置
axislabel_opts=opts.LabelOpts(color='#33a3dc'), # x轴标签配置
),
yaxis_opts=opts.AxisOpts(
splitline_opts=opts.LineStyleOpts(is_show=True, opacity=1),
axislabel_opts=opts.LabelOpts(color='#33a3dc'),
)
)
.set_series_opts(
label_opts=opts.LabelOpts(position='right', color='#ff1435') # 配置标签项位置和颜色
)
.reversal_axis() # 坐标轴翻转
)
grid = (
Grid()
.add(bar, grid_opts=opts.GridOpts(pos_left='25%', pos_top='8%'))
)
else:
continue
t.add(grid, '{}'.format(df.loc[i + 1, 50])) # 将Bar添加至时间轴组件中
# 配置Timeline参数
t.add_schema(
play_interval=500, # 播放速度/间隔(单位:ms)
is_auto_play=True, # 是否自动播放
is_loop_play=True, # 是否循环播放
is_timeline_show=False,# 是否显示timeline组件
)
return t.render_notebook() # 输出为网页
draw_timeline()
(代码运行完之后为此图为动态图)