基于python爬虫的微博热搜榜分析
实现内容
1.爬取微博热搜top50的相关信息存入exacl表格中
2.将爬取的热点进行分词,统计分词频率,做词云可视化分析
3.进行热点的热度区间分析,时间线分析,类型类别分析
1.爬取微博热搜的相关信息存入exacl表格中
采用 cookie 拟登陆来获取访问许可,使用正则表达式来进行微博热搜信息的爬取,爬取信息主要有时间、排名、热搜内容、热度、类型类别。之后通过 xlwt 库中的Workbook 创建 exacl 表格,用 book 对象调用 add_sheet 方法来建立一张 sheet 表,利用循环列表的方式将数据插入 exacl 表格中并保存
部分实现代码如下:
def conent_url():
r = requests.get(url, headers=header)
r.encoding = "utf-8"
soup = r.text
#print(soup)
rank = re.findall(r'<td class="td-01 ranktop">(.*)</td>', soup)#匹配排名
title=re.findall(r'<a href=".*?Refer=top" target="_blank">(.*?)</a>',soup)#匹配热搜名称
number=re.findall(r'<a href=".*?Refer=top" target="_blank">.*?</a>\n\s*<span>(.*?)</span>',soup)#匹
配热度
cate = re.findall(r'<td class="td-03">(.*)</td>', soup)#匹配类别
for i in cate:#有些类别未知做一个判断
if len(i) != 0:
excot = re.sub('[^\u4e00-\u9fa5]+', '', str(i))
cate_list.append(excot)
else:
6
cate_list.append('未知')
cate_list.pop(0)#移除第一个元素
nowtime=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))获取当前时间
#data_time.append(rank)
#print(len(data_time))
for k in range(0,50):
data_time.append(nowtime)
datalist.append(data_time)
datalist.append(rank)
datalist.append(title)
datalist.append(number)
datalist.append(cate_list)
#print(datalist)
book=xlwt.Workbook(encoding='utf-8')#创建 excel 表格类型文件
sheet = book.add_sheet('微博热搜', cell_overwrite_ok=True)#用 book 对象调用 add_sheet 方法来建立
一张 sheet 表,
head = ("时间","排名", "内容", "热度","类型")#设置标题
for i in range(0, 5):#将数据按五列循环放入 excal 表
sheet.write(0, i, head[i])
for j in range(len(datalist)):
data = datalist[j]
for i in range(len(rank)):
sheet.write(i+1, j, data[i])
book.save("C:\pytest\微博热搜 5.xls")#保存文件位置
2.把收集到的信息汇总到同一张表格中
定义文件保存的目录,找到文件路径下的所有表格名称,保存到列表,拼接文件的路径,读取文件的数据到 DataFrame,存入新的列表,将 DataFrame 合并存入新的exacl 文件(实现同一文件夹中exacl文件的合并)
部分实现代码如下:
#文件路径
file_dir = r'C:\pytest'
#构建新的表格名称
new_filename = file_dir + '\\6 月 22 日微博热搜.xls'
#找到文件路径下的所有表格名称,返回列表
file_list = os.listdir(file_dir)
l=len(file_list)
new_list = []
for file in file_list:
#重构文件路径
file_path = os.path.join(file_dir,file)
#将 excel 转换成 DataFrame
dataframe = pd.read_excel(file_path)
#保存到新列表中
new_list.append(dataframe)
#多个 DataFrame 合并为一个
df = pd.concat(new_list)
#写入到一个新 excel 表中
df.to_excel(new_filename,index=False)
print("\n%d 个文件合并成功"%l)
3.将爬取的热点进行分词,统计分词频率,做词云可视化分析
使用 pd.read_excel 读取微博热搜,用 usecols 参数选择读取 exacl 表第三列,也就是微博热搜标题,将热搜标题存入一个列表中,用 join 函数将列表转化为字符串,使用 jieba.lcut 进行分词,对分词进行处理去掉空格、单个字符。然后统计分词频率输出前二百的分词,使用 WordCloud 库进行词云制作。
部分实现代码如下
def data_proc():#读取微博热搜,对微博热搜进行分词,制作词云
data=pd.read_excel('C:\pytest\\6 月 22 日微博热搜.xls',usecols=[2],names=None)#使用 usecols 参数选
择读取 exacl 表第三列
data_cy = data.copy()# 为了不影响原数据,所以拷贝一份
#print(data_cy)
df=data_cy.values.tolist()#每一行数据转化为一个列表
#print(df)
for i in df:
datalist.append(i[0])#将所有数据存入到一个列表中
#print(datalist)
string = ' '.join(datalist)#将列表中数据转化为以空格划分为字符串
#print(string)
exact = jieba.lcut(string,cut_all=False)#精确模式分词
for i in exact:
if i !=' ' and len(i)!=1:
word.append(i)
else:
pass#对分词进行一个处理,去掉空格,以及常用词
#print(word)
# 词频统计
word_counts = collections.Counter(word) # 对分词做词频统计
10
print(word_counts)
word_counts_top = word_counts.most_common(100)#前 200 的分词进行输出
print(word_counts_top)
#设置词云
my_cloud = WordCloud(
background_color='white', # 设置背景颜色 默认是 black
width=900, height=600,
max_words=100, # 词云显示的最大词语数量
font_path='simhei.ttf', # 设置字体 显示中文
max_font_size=99, # 设置字体最大值
min_font_size=16, # 设置子图最小值
random_state=50 # 设置随机生成状态,即多少种配色方案
).generate_from_frequencies(word_counts)
# 显示生成的词云图片
plt.imshow(my_cloud, interpolation='bilinear')
# 显示设置词云图中无坐标轴
plt.axis('off')
plt.show()
代码运行结果如下
4.进行热点的热度区间分析,时间线分析,类型类别分析
统计表格中的数据总数,将数据从表格中取出,对热度进行 if 判断来划分区间。对时间线的分析主要是根据每隔一段时间抓取的前 50 热搜榜,判断不同时间热搜榜前五十的变化来进行时间线的分析,热搜类型是和热度在同一列下,将热搜类型与热度做以个正则表达式,只匹配汉字或数字进行提取,若没有提取到类型则输出未知,最后进行词频统计,来统计那些类型热度比较高;类别统计是判断新出现的热搜有多少,爆火的和热门的热搜有多少
部分实现代码如下
def number_body():#热度
number=pd.read_excel('C:\pytest\\6 月 22 日微博热搜.xls',usecols=[3],names=None)#使用 usecols 参
数选择读取 exacl 表第四列
data_cy = number.copy()# 为了不影响原数据,所以拷贝一份
#print(data_cy)
df=data_cy.values.tolist()#每一行数据转化为一个列表
#print(df)
for i in df:
str=re.findall('\d+',i[0])#只匹配数字
#print(str)
if str!='':#不是空的存入列表
number_list.append(str[0])#将所有数据存入到一个列表中
else:
pass
n1 = len(title_list)
n2 = len(number_list)
if n1 == n2:#主要是对从 exacl 表格中读取的数据进行核对
print("一共包含数据%d 条" % n1)
else:
print("erro")
for l in number_list:#数据分析
i=int(l)#类型转换
if i >=3000000:#300 万以上热度的个数和事件
k = (number_list.index(l))
list1.append(l+' '+title_list[k])
else:
if i >=2000000:#300 万到 200 万热度的个数和事件
k = (number_list.index(l))
list2.append(l +' '+title_list[k])
else:
if i>=1000000:#100 万到 200 万热度的个数和事件
k = (number_list.index(l))
list3.append(l +' '+title_list[k])
else:
k = (number_list.index(l))##100 万以下热度的个数和事件
list4.append(l + ' ' + title_list[k])
print('热度在 300 万以上的有%d 个'%len(list1),'为',list1)
print('热度在 200 万到 300 万的有%d 个'%len(list2),'为',list2)
print('热度在 100 万到 200 万的有%d 个'%len(list3),'为',list3)
print('热度在 100 万以下的有%d 个'%len(list4),'为',list4)
print('************************************')
print('以下为时间线分析:')
print('************************************')
def timeline():
list1 = []
list2 = []
for i in title_list:
if i not in list1:
list1.append(i)#收集的热搜,去重
for a in list1:#获取热搜中相同标题的位置
id1 = [i for i, x in enumerate(title_list) if x == a]
list2.append(id1)
for i in range(0, len(list2)):
c = list2[i]
if len(c)==1:
print('暂未收集到 《'+title_list[c[0]]+'》 的时间线')
else:
for d in range(0, len(c)):
ll=[time_list[c[d]]+' <'+title_list[c[d]]+'> '+number_list[c[d]]]
list5.append(ll)
print('时间线',list5)
list5.clear()
def category_body():#热搜类别
category = pd.read_excel('C:\pytest\\6 月 22 日微博热搜.xls', usecols=[3], names=None) # 使用
usecols 参数选择读取 exacl 表第四列
data_cy = category.copy() # 为了不影响原数据,所以拷贝一份
# print(data_cy)
df = data_cy.values.tolist() # 每一行数据转化为一个列表
# print(df)
for i in df:
str = re.sub('[^\u4e00-\u9fa5]+','',i[0])#只匹配汉字
if str != '':
category_list.append(str) # 将所有数据存入到一个列表中
else:
category_list.append('未知')
word_counts = collections.Counter(category_list)
print('类别分析',dict(word_counts))
def cate_body():
cate = pd.read_excel('C:\pytest\\6 月 22 日微博热搜.xls', usecols=[4], names=None) # 使用 usecols 参
数选择读取 exacl 表第五列
data_cy = cate.copy() # 为了不影响原数据,所以拷贝一份
# print(data_cy)
df = data_cy.values.tolist() # 每一行数据转化为一个列表
# print(df)
for i in df:
cate_list.append(i[0]) # 将所有数据存入到一个列表中
word_numberr = collections.Counter(cate_list)
print('类型分析', dict(word_numberr))
代码运行结果如下
总结
大概就是这样,还有待改进学习。