百度热搜爬虫分析

一、选题背景

如今,我们日常生活获取到的信息渠道有很多种。如视频、文章、报纸、音频。像获取新闻热点平台有:百度、今日头条、抖音、bilibili、新浪微博、网易新闻……百度热搜以数亿用户海量的真实数据为基础,通过专业的数据挖掘方法,计算关键词的热搜指数,旨在建立权威、全面、热门、时效的各类关键词排行榜,引领热词阅读时代。此次课题依据百度热搜指数进行爬取可视化分析。

 

二、爬虫方案设计

  名称:百度热搜爬虫系统

  2.1爬取内容与数据特征分析

  爬取内容:热搜、小说、热搜指数。

  数据特征分析:网页文本。

  2.2主题式网络爬虫设计方案概述

  方案概述:

  1. 利用request进行访问请求
  2. 解析网页内容,这里使用xtree.xpath进行网页解析。
  3. 数据存储,利用open()函数创建表格模板、wirtelines()函数进行输出存储。
  4. 查看网页结构。
  5. 查看网页爬取内容的位置。
  6. 取出数据。
  7. 遍历数据。
  8. 数据存储。

  

  2.2.1 思路

  1. 查看网页结构。
  2. 查看网页爬取内容的位置。
  3. 取出数据。

  2.2.2技术难点

  1. 异常处理。
  2. 网页内容读取,xtree第三方库用法。
  3. 数据遍历。
  4. 数据批量存储
  5. 整体系统设计。

三、技术难点

  3.1主题页面的结构特征与分析

 

百度热搜 (baidu.com)

 

  

  3.2 Htmls 页面解析

 

将关键词与url进行贴合成为访问的url。之后调用相对应关键词

 

url ='https://top.baidu.com/board?tab={}'.format

 

(Baidu_hotdic["?"])

 

             realtime()

 

  页面解析:

      title:爬取的title名在<div class="c-single-text-ellipsis">  从六中全会公报看世界第一大党 <!--39--></div>

                                     

      热度指数:<div class="hot-index_1Bl1a"> 4967498 </div>

     

  3.3节点查找方法与遍历方法 

  查找节点:

     标题:

   hot_title=html.xpath('//[@id="sanRoot"]/main/div[2]/div/div[2]/div[{}]/div[2]/a/div[1])

    热度指数:

    hot_zhishu=html.xpath('//*[@id="sanRoot"]/main/div[2]/div/div[2]/div[{}]/div[1]/div[2])

 

  遍历方法:

     采用for循环把内容取出。

四、网络爬虫设计

  4.1数据爬取与采集

  代码分析:

Main函数:
        代码分析:主函大概代码意思是,根据输入的关键词,将关键词与url进行贴合成为访问的url。之后调用相对应关键词的数据爬取方法。
        if __name__ == '__main__':
            while(True):
hot = input("输入热搜关键词:热搜、小说、电影、电视剧、动漫、综艺、纪录片、汽车、游戏。\n")
                if hot in "热搜":
                    url ='https://top.baidu.com/board?tab={}'.format
(Baidu_hotdic["热搜"])
                        realtime()
                elif hot in "小说":
                    url = 'https://top.baidu.com/board?tab={}'.format
(Baidu_hotdic["小说"])
                    novel()
                elif hot in "电影":
                    url = 'https://top.baidu.com/board?tab={}'.format
(Baidu_hotdic["电影"])
                    movie()
               elif hot in "电视剧":
                    url = 'https://top.baidu.com/board?tab={}'.format
(Baidu_hotdic["电视剧"])
                   teleplay()
                elif hot in "动漫":
                    url = 'https://top.baidu.com/board?tab={}'.format
(Baidu_hotdic["动漫"])
                   cartoon()
                elif hot in "综艺":
                    url = 'https://top.baidu.com/board?tab={}'.format
(Baidu_hotdic["综艺"])
                    variety()
                elif hot in "纪录片":
                    url = 'https://top.baidu.com/board?tab={}'.format
(Baidu_hotdic["纪录片"])
                    documentary()
                elif hot in "汽车":
                    url = 'https://top.baidu.com/board?tab={}'.format
(Baidu_hotdic["汽车"])
                    car()
                elif hot in "游戏":
                    url = 'https://top.baidu.com/board?tab={}'.format
(Baidu_hotdic["游戏"])
                    game()
                else:
                    print("搜索词错误!!!")

            choice = input("继续还是结束:")
            if choice in "继续":
            continue
            elif choice in "结束":
            break
            else:
            print("输入有误!")



功能代码:
def realtime():
    # 创建hot_realtime.csv
    file = open("hot_realtime.csv", "a")
    #定义表格模板并关闭表格
    file.write("hot_title" + "," + "hot_zhishu" + '\n')  
    file = file.close()
    #请求访问
    req = requests.get(url=url,headers=headers)
    # print(req.text)
    #解析页面
    html = etree.HTML(req.text)
    count = 1
    print("\t标题\t\t\t\t\t\t", "指数")
    #for循环内容提取
    for i in range(1,31):
         #xpath()定位目标位置
        hot_title = html.xpath('//*[@id="sanRoot"]/main/div[2]
/div/div[2]/div[{}]/div[2]/a/div[1]/text()'.format(count))
#从列表中提取出内容转换成字符串类型
        for i in hot_title:
           hot_title = i
hot_zhishu = html.xpath('//*[@id="sanRoot"]/main
/div[2]/div/div[2]/div[{}]/div[1]/div[2]/text()'.format(count))
        for i in hot_zhishu:
            hot_zhishu = i
        #打开文件并保存数据
        with open("hot_realtime.csv", "a") as f:
             #将数据写入表格中
            f.writelines(hot_title + "," + hot_zhishu + '\n')
            f.close()
        count += 1
        print(hot_title,hot_zhishu)

  4.2爬虫系统运行

    

    

  

  4.2数据清洗与处理

  数据导入:

import seaborn as sns
import matplotlib.pyplot as plt
import numpy as mp
from scipy.optimize import leastsq
import pandas as pd
realtime = pd.read_excel('hot_realtime.xlsx')
novel = pd.read_excel('hot_novel.xlsx')

  数据清洗处理:

# 重复值处理
realtime = realtime.drop_duplicates('name')
# Nan处理
realtime = realtime.dropna(axis = 0)
#空白值处理
realtime = realtime.dropna()
# 删除无效行
realtime = realtime.drop([''], axis = 1)
realtime
# 重复值处理
novel = novel.drop_duplicates('name')
# Nan处理
novel = novel.dropna(axis = 0)
#空白值处理
novel = novel.dropna()
# 删除无效行
novel = novel.drop([''], axis = 1)
novel

  4.3数据可视化分析

# 价格进行降序排列分析
x = novel['hot_title']
y = novel['hot_zhishu']
fig = plt.figure(figsize=(10, 4), dpi=80)
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False
plt.xticks(rotation=90)
plt.plot(x,y,'s-',color = 'purple',label="热度")#s-:方形
plt.legend(loc = "best")#图例
plt.title("小说热度趋势图",fontsize=18)
plt.xticks(fontsize=12)
plt.ylabel("热度指数",fontsize=12)#纵坐标名字
plt.show()

 

# 价格进行降序排列分析
x = realtime['hot_title']
y = realtime['hot_zhishu']
fig = plt.figure(figsize=(10, 4), dpi=80)
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False
plt.xticks(rotation=90)
plt.plot(x,y,'s-',color = 'r',label="热度")#s-:方形
plt.legend(loc = "best")#图例
plt.title("实时热点趋势图",fontsize=18)
plt.xticks(fontsize=12)
plt.ylabel("热度指数/百万",fontsize=12)#纵坐标名字
plt.show()

 

x = realtime['hot_title']
y = realtime['hot_zhishu']
fig = plt.figure(figsize=(10, 4), dpi=80)
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False
plt.xticks(rotation=90)
plt.bar(x,y,alpha=0.2, width=0.6, color='b', lw=3)
plt.legend(loc = "best")#图例
plt.title("实时热点柱状图",fontsize=18)
plt.xticks(fontsize=12)
plt.ylabel("热度指数/百万",fontsize=12)#纵坐标名字
plt.show()

 

# 价格进行降序排列分析
x = novel['hot_title']
y = novel['hot_zhishu']
fig = plt.figure(figsize=(10, 4), dpi=80)
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False
plt.xticks(rotation=90)
plt.bar(x,y,alpha=0.2, width=0.6, color='k', lw=3)
plt.legend(loc = "best")#图例
plt.title("小说热度柱状图",fontsize=18)
plt.xticks(fontsize=12)
plt.ylabel("热度指数",fontsize=12)#纵坐标名字
plt.show()

 

 

# 水平图
x = realtime['hot_title']
y = realtime['hot_zhishu']
fig = plt.figure(figsize=(10, 8), dpi=80)
plt.barh(x,y, alpha=0.2, height=0.6, color='coral')
plt.title("时事热点水平图",fontsize=18)
plt.legend(loc = "best")#图例
# plt.xticks(rotation=180)
plt.xlabel("热度指数/百万",fontsize=12)#纵坐标名字

 

 

# 水平图
x = novel['hot_title']
y = novel['hot_zhishu']
fig = plt.figure(figsize=(10, 8), dpi=80)
plt.barh(x,y, alpha=0.2, height=0.6, color='dodgerblue')
plt.title("小说热度水平图",fontsize=18)
plt.legend(loc = "best")#图例
# plt.xticks(rotation=180)
plt.xlabel("热度指数",fontsize=12)#纵坐标名字

 

 

 

# 散点图
x = realtime['hot_title']
y = realtime['hot_zhishu']
fig = plt.figure(figsize=(10, 6), dpi=80)
ax = plt.subplot(1, 1, 1)
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.scatter(x,y,color='b',marker='o',s=60,alpha=1)
plt.xticks(rotation=90)
plt.xticks([])
plt.ylabel("热度",fontsize=12)#横坐标名字
plt.title("时事热点散点图",fontsize=16)

 

 

# 散点图
x = novel['hot_title']
y = novel['hot_zhishu']
fig = plt.figure(figsize=(10, 6), dpi=80)
ax = plt.subplot(1, 1, 1)
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.scatter(x,y,color='c',marker='o',s=60,alpha=1)
plt.xticks(rotation=90)
plt.xticks([])
plt.ylabel("热度",fontsize=12)#横坐标名字
plt.title("小说热度散点图",fontsize=16)

 

# 盒图
y = novel['hot_zhishu']
plt.boxplot(y)
plt.title("小说热度盒图",fontsize=16)
plt.show()

 

# 盒图
y = realtime['hot_zhishu']
plt.boxplot(y)
plt.title("时事热点盒图",fontsize=16)
plt.show()

  线性回归

plt.rcParams['font.sans-serif'] = ['SimHei']#解决乱码问题
#定义变量
novel=novel.loc[:,'hot_zhishu']
realtime=realtime.loc[:,'hot_zhishu']
#函数表达式
def func(params,x):
    a,b,c=params
    return a*x*x+b*x+c
def error_func(params,x,y):
    return func(params,x)-y
P0=[1,9.0]
def main():
    plt.figure(figsize=(8,6))
    P0=[1,9.0,1]
    Para=leastsq(error_func,P0,args=(gsgm,zprs))
    a,b,c=Para[0]
    print("a=",a, "b=",b, "c=",c)
    #绘图
    plt.scatter(novel,realtime,color="dodgerblue",label="样本数据",linewidth=2)
    x=mp.linspace(655245,200,4000)
    y=a*x*x+b*x+c
    #右上角标
    plt.plot(x,y,color="red",label="拟合曲线",linewidth=2)
    #x,y轴名称
    plt.xlabel('novel')
    plt.ylabel('realtime')
    #标题
    plt.title("novel与realtime回归方程")
    plt.grid()
    plt.legend()
    plt.show()
    print(x)
    print(y)
main()

  

 

  

   4.4文本分析

  

# 词云
import random
import wordcloud as wc
import matplotlib.pyplot as plt

# 定义图片尺寸
word_cloud = wc.WordCloud(
   background_color='black',  
   font_path='msyhbd.ttc',  
   max_font_size=300, 
   random_state=50,  
                       )
text = realtime['hot_title']
text = " ".join(text)
# 绘制词云
fig = plt.figure(figsize=(8, 4), dpi=80)
ax = plt.subplot(1, 1, 1)
word_cloud.generate(text)
plt.imshow(word_cloud)
plt.show()

 

# 词云
import random
import wordcloud as wc
import matplotlib.pyplot as plt

# 定义图片尺寸
word_cloud = wc.WordCloud(
   background_color='black',  
   font_path='msyhbd.ttc',  
   max_font_size=300, 
   random_state=50,  
                       )
text = novel['hot_title']
text = " ".join(text)
# 绘制词云
fig = plt.figure(figsize=(8, 4), dpi=80)
ax = plt.subplot(1, 1, 1)
word_cloud.generate(text)
plt.imshow(word_cloud)
plt.show()

 

 五、总结

1.经过对主题数据的分析与可视化,可以得到哪些结论?是否达到预期的目标?

根据热搜指数分析出近期实事热点是“十九届六中全会决议中的10个明确”,小说热度最高的是《逆天邪神》。分析结果达到预期

2.在完成此设计过程中,得到哪些收获?以及要改进的建议?

 在此次设计过程种我对数据处理种的数据筛出有了很大的收获,譬如怎么进行类型转换,然后达到自己的想要的效果。受益匪浅,需要改进的地方可能就是编写程序反应时间过慢编程经验比较欠缺。