爬取百度热搜榜

一、主题式网络爬虫设计方案

1.主题式网络爬虫名称:爬取百度热搜榜

2.主题式网络爬虫爬取的的内容:爬取百度热搜前十

3.主题式网络爬虫设计方案概述:

实现思路:通过分析网页源代码,找出数据所在的标签,通过爬虫读取数据保存到csv文件中,读取文件,对数据进行清洗和处理,然后在进行分析与可视化并建立回归方程。

技术难点:知识掌握不充分,对网页爬取还有很多不懂。

二、主题页面的结构特征分析

1.主题页面的结构与特征分析:从网络源代码可以看出,我们所需要的字段全部在id=“hot-list”这个ul标签下的所有li标签中。所以要在整个HTML页面中,首先找到ul标签,获取所需要的热搜榜信息,然后在ul标签中解析所有的li标签,获取所需要的关键词和搜索指数信息。

 

 3.节点(标签)查找方法与遍历方法:进入百度热搜页面点击F12打开网络源代码,查询需要的标签属性关键字,可以看到所需要的字段所在的标签位置。用request.get(url)命令向服务器提交请求,然后将响应的网页信息交由BeautifulSoup库解析。提取HTML结构和源代码,最后用soup.prettify()方法输出源码。

三、网络爬虫程序设计

1.数据爬取与采集

 

import requests
from bs4 import BeautifulSoup
url='http://top.baidu.com/'#选择要爬取的网站
def getHTMLText(url):
    try:
        r=requests.get(url)#获得url信息
        r.raise_for_status()#失败请求(非200响应)抛出异常
        r.encoding = r.apparent_encoding#根据内容分析出的编码方式,备选编码;  
        return r.text
    except:
        return""
def get_data(html):
    #创建空列表
    top=[]
    keyword=[]
    hot=[]
    soup=BeautifulSoup(html,"html.parser")#使用BeautifulSoup解析文本
    for x in soup.find_all(class_="num-top"):
        top.append(x.get_text().strip())
    for y in soup.find_all(class_="list-title"):
        keyword.append(y.get_text().strip())
    for z in soup.find_all(class_="icon-rise"):
        hot.append(z.get_text().strip())
    final_list=[top,keyword,hot]#把列表放入变量final_list中
    return final_list
def main():
    url='http://top.baidu.com/'
    html=getHTMLText(url)
    final_list=get_data(html)
    return final_list
import pandas as pd
df=pd.DataFrame(main(),index=["排名","关键词","搜索指数"])#数据可视化
print(df.T)
filename=("百度热搜榜.csv")
df.to_csv(filename)
         

 

 

2.对数据进行清洗和处理

df.duplicated()#查找重复值
df.drop_duplicates()#删除重复值
df.isnull()#统计空值
df.describe()#描述数据

 

 

 

 

 

 

 

 

 

 4.数据分析与可视化

#垂直柱形图
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['STSong']#用来正常显示中文标签
plt.figure()
plt.bar(['全国义务教育辍学学生降至2419人','联合国指出当今世界面临5大挑战','中印两军举行第六轮军长级会谈','曲婉婷为贪污3.5亿入狱母亲喊冤','2020年诺贝尔奖颁奖改为线上举行'],[4903555,4731930,4566313,4406492, 4252264])
plt.xlabel("关键词")
plt.ylabel("搜索指数")
plt.show()
#水平柱形图
plt.barh(['全国义务教育辍学学生降至2419人','联合国指出当今世界面临5大挑战','中印两军举行第六轮军长级会谈','曲婉婷为贪污3.5亿入狱母亲喊冤','2020年诺贝尔奖颁奖改为线上举行'],[4903555,4731930,4566313,4406492, 4252264])
plt.xlabel("搜索指数")
plt.ylabel("关键词")
plt.show()

 

 

#散点图
plt.scatter(['全国义务教育辍学学生降至2419人','联合国指出当今世界面临5大挑战','中印两军举行第六轮军长级会谈','曲婉婷为贪污3.5亿入狱母亲喊冤','2020年诺贝尔奖颁奖改为线上举行'],[4903555,4731930,4566313,4406492, 4252264])
plt.xlabel("关键词")
plt.ylabel("搜索指数")
plt.title("百度热搜散点图")
plt.show()

 

 

#折线图
plt.plot(['全国义务教育辍学学生降至2419人','联合国指出当今世界面临5大挑战','中印两军举行第六轮军长级会谈','曲婉婷为贪污3.5亿入狱母亲喊冤','2020年诺贝尔奖颁奖改为线上举行'],[4903555,4731930,4566313,4406492, 4252264])
plt.xlabel("关键词")
plt.ylabel("搜索指数")
plt.title("百度热搜折线图")
plt.show()

 

 

#堆叠图图
plt.stackplot(['全国义务教育辍学学生降至2419人','联合国指出当今世界面临5大挑战','中印两军举行第六轮军长级会谈','曲婉婷为贪污3.5亿入狱母亲喊冤','2020年诺贝尔奖颁奖改为线上举行'],[4903555,4731930,4566313,4406492, 4252264])
plt.xlabel("关键词")
plt.ylabel("搜索指数")
plt.title("百度热搜堆叠图")
plt.show()

 

 

#盒图
import seaborn as sns
sns.boxplot(['全国义务教育辍学学生降至2419人','联合国指出当今世界面临5大挑战','中印两军举行第六轮军长级会谈','曲婉婷为贪污3.5亿入狱母亲喊冤','2020年诺贝尔奖颁奖改为线上举行'],[4903555,4731930,4566313,4406492, 4252264])

 

 5.根据数据之间的关系,分析两个变量之间的相关系数,画出散点图,并建立变量之间的回归方程(一元或多元)

 

import scipy as sp
import matplotlib
from scipy.optimize import leastsq
from numpy import genfromtxt
colnames=["关键词","搜索指数"]
X=np.array(keyword)
Y=np.array(hot)
def fit_func(p,x):
    k,b=p
    return k*x+b
def error_func(p,x,y):
    return fit_func(p,x)-y
def main():
    plt.figure(figsize=(10,6))#指定图像比例
    p0=[0,0]
    Para=leastsq(error_func,p0,args=(X,Y))#读取leastsq返回值结果
    k,b=Para[0]
    print("k=",k,"b=",b)
    plt.scatter(X,Y,color="green",label="样本数据",linewidth=2)
    #画拟合曲线
    x=np.linspace(43000,49000,5)
    y=k*x+b
    plt.plot(x,y,color="red",label="拟合曲线",linewidth=2)
    plt.title("百度热搜榜")
    plt.grid()
    plt.legend()
    plt.show()

6.数据持久化

import csv
with open("百度热搜榜.csv","r") as csvfile:
    read=csv.reader(csvfile)
    for i in read:
        print(i)
with open("百度热搜榜.csv","w") as csvfile:
    write=csv.writer(csvfile)
    write.writerow(data)
    write.writerows(data)

7.将以上各部分的代码汇总,附上完整程序代码

import requests
from bs4 import BeautifulSoup
url='http://top.baidu.com/'#选择要爬取的网站
def getHTMLText(url):
    try:
        r=requests.get(url)#获得url信息
        r.raise_for_status()#失败请求(非200响应)抛出异常
        r.encoding = r.apparent_encoding#根据内容分析出的编码方式,备选编码;  
        return r.text
    except:
        return""
def get_data(html):
    #创建空列表
    keyword=[]
    hot=[]
    soup=BeautifulSoup(html,"html.parser")#使用BeautifulSoup解析文本
    for x in soup.find_all(class_="list-title"):
        keyword.append(x.get_text().strip())
    for y in soup.find_all(class_="icon-rise"):
        hot.append(y.get_text().strip())
    final_list=[keyword,hot]#把列表放入变量final_list中
    return final_list
def main():
    url='http://top.baidu.com/'
    html=getHTMLText(url)
    final_list=get_data(html)
    return final_list
import pandas as pd
df=pd.DataFrame(main(),index=["关键词","搜索指数"])#数据可视化
print(df.T)
df.to_csv("百度热搜榜.csv",encoding="utf_8")
df.duplicated()#查找重复值
df.drop_duplicates()#删除重复值
df.isnull()#统计空值
df.describe()#描述数据
#垂直柱形图
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['STSong']#用来正常显示中文标签
plt.figure()
plt.bar(['全国义务教育辍学学生降至2419人','联合国指出当今世界面临5大挑战','中印两军举行第六轮军长级会谈','曲婉婷为贪污3.5亿入狱母亲喊冤','2020年诺贝尔奖颁奖改为线上举行'],[4903555,4731930,4566313,4406492, 4252264])
plt.xlabel("关键词")
plt.ylabel("搜索指数")
plt.title("百度热搜垂直柱形图")
plt.show()
#水平柱形图
plt.barh(['全国义务教育辍学学生降至2419人','联合国指出当今世界面临5大挑战','中印两军举行第六轮军长级会谈','曲婉婷为贪污3.5亿入狱母亲喊冤','2020年诺贝尔奖颁奖改为线上举行'],[4903555,4731930,4566313,4406492, 4252264])
plt.xlabel("搜索指数")
plt.ylabel("关键词")
plt.title("百度热搜水平柱形图")
plt.show()
#散点图
plt.scatter(['全国义务教育辍学学生降至2419人','联合国指出当今世界面临5大挑战','中印两军举行第六轮军长级会谈','曲婉婷为贪污3.5亿入狱母亲喊冤','2020年诺贝尔奖颁奖改为线上举行'],[4903555,4731930,4566313,4406492, 4252264])
plt.xlabel("关键词")
plt.ylabel("搜索指数")
plt.title("百度热搜散点图")
plt.show()
#折线图
plt.plot(['全国义务教育辍学学生降至2419人','联合国指出当今世界面临5大挑战','中印两军举行第六轮军长级会谈','曲婉婷为贪污3.5亿入狱母亲喊冤','2020年诺贝尔奖颁奖改为线上举行'],[4903555,4731930,4566313,4406492, 4252264])
plt.xlabel("关键词")
plt.ylabel("搜索指数")
plt.title("百度热搜折线图")
plt.show()
#堆叠图图
plt.stackplot(['全国义务教育辍学学生降至2419人','联合国指出当今世界面临5大挑战','中印两军举行第六轮军长级会谈','曲婉婷为贪污3.5亿入狱母亲喊冤','2020年诺贝尔奖颁奖改为线上举行'],[4903555,4731930,4566313,4406492, 4252264])
plt.xlabel("关键词")
plt.ylabel("搜索指数")
plt.title("百度热搜堆叠图")
plt.show()
import seaborn as sns
sns.boxplot(['全国义务教育辍学学生降至2419人','联合国指出当今世界面临5大挑战','中印两军举行第六轮军长级会谈','曲婉婷为贪污3.5亿入狱母亲喊冤','2020年诺贝尔奖颁奖改为线上举行'],[4903555,4731930,4566313,4406492, 4252264])
import scipy as sp
import matplotlib
from scipy.optimize import leastsq
from numpy import genfromtxt
colnames=["关键词","搜索指数"]
X=np.array(keyword)
Y=np.array(hot)
def fit_func(p,x):
    k,b=p
    return k*x+b
def error_func(p,x,y):
    return fit_func(p,x)-y
def main():
    plt.figure(figsize=(10,6))#指定图像比例
    p0=[0,0]
    Para=leastsq(error_func,p0,args=(X,Y))#读取leastsq返回值结果
    k,b=Para[0]
    print("k=",k,"b=",b)
    plt.scatter(X,Y,color="green",label="样本数据",linewidth=2)
    #画拟合曲线
    x=np.linspace(43000,49000,5)
    y=k*x+b
    plt.plot(x,y,color="red",label="拟合曲线",linewidth=2)
    plt.title("百度热搜榜")
    plt.grid()
    plt.legend()
    plt.show()
import csv
with open("百度热搜榜.csv","r") as csvfile:
    read=csv.reader(csvfile)
    for i in read:
        print(i)
with open("百度热搜榜.csv","w") as csvfile:
    write=csv.writer(csvfile)
    write.writerow(data)
    write.writerows(data)

四、结论

1.经过对主题数据的分析与可视化,可以得到哪些结论?

经过对数据的分析与可视化,我们可以清晰的了解数据之间的相关关系,这有助于解决大部分人工计算绘图的问题。

2.对本次程序设计任务完成的情况做一个简单的小结

通过这次任务,我学会了数据的分析与可视化,并掌握了不少库的使用,过程中也参考了不少百度资料,这也加深了我对学习python的兴趣。

posted @ 2020-09-24 23:00  李祖淇  阅读(996)  评论(0编辑  收藏  举报