一.主题式网络主题式网络爬虫设计方案
1.主题式网络爬虫名称:爬取微博热搜排行榜并进行保存可视化
2.主题式网络爬虫爬取的内容:爬取微博热搜排行榜前五十
3.主题式网络爬虫设计方案概述:
先使用代码爬取网页的结构:
import requests
from bs4 import BeautifulSoup
url='https://s.weibo.com/top/summary?Refer=top_hot&topnav=1&wvr=6'
def getHTMLText(url,timeout=30):
try:
r=requests.get(url,timeout=30)
r.raise_for_status()
r.encoding=r.apparent_encoding
return r.text
except:
return'产生异常'
html=getHTMLText(url)
soup=BeautifulSoup(html,'html.parser')
print(soup.prettify())
然后打开所要爬取的网页,进入开发者工具中
经过查找,发现我们所需的热搜排名与热搜的标题以及热度分别藏在class="td-01 ranktop"与class="td_02"当中
接着进行爬取并采集数据:
#引入所需要到的第三方库
import requests
from bs4 import BeautifulSoup
import pandas as pd
from pandas import DataFrame
import csv
#输入所要爬取的网页
url="https://s.weibo.com/top/summary?Refer=top_hot&topnav=1&wvr=6"
#伪装爬虫头避免被检测拦截
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}
#请求网站
r=requests.get(url)
print(r.text)
#对页面内容重新编码
r.encoding=r.apparent_encoding
data=r.text
#使用BeautifulSoup
soup=BeautifulSoup(data,'html.parser')
#显示网站结构
print(soup.prettify())
#解析网页了解到热搜排名和热搜标题热度分别放在两个class当中,创建两个个空列表
head=[]
index=[]
#把排名添加进空列表
for i in soup.find_all(class_="td-01 rank top"):
head.append(i.get_text().strip())
#把热度标题添加进空列表
for k in soup.find_all(class_="td-02"):
index.append(k.get_text().strip())
data=[head,index]
print(data)
s=pd.DataFrame(data,index=["排名","标题\热度数据"])
#将所得数据进行可视化
print(s.T)
接着进行数据的保存:
#将数据保存至本地并进行数据的清理
S="D:\爱剪辑\\wbrs2.xlsx"
df=pd.DataFrame(data,index=["排名","标题\热度数据"])
print(df.T)
df.T.to_excel(S)
#进行数据处理
print(df.isnull())
print(df.duplicated())
print(df.isna().head())
print(df.describe())
titanic=pd.DataFrame(pd.read_excel('D:\爱剪辑\\wbrs2.xlsx'))
titanic.drop_duplicates()
titanic.head()
#将保存至本地的数据加载到DataFrame中
wbrs2_df=pd.read_excel('D:\爱剪辑\\wbrs2.xlsx',sheet_name='Sheet1')
wbrs2_df.head()
wbrs2_df.describe()
接着进行数据可视化:
#导入作图所需的库
import matplotlib
import pandas as pd
from matplotlib import pyplot as plt
#读取并可视化数据
file_path="D:\爱剪辑\\wbrs2.xlsx"
df=pd.read_excel(file_path,name=['排名','标题','热度数据'])
df.set_index('排名',inplace=True)
df.head()
print(df.head())
#做出数据前五散点图
def Scatter_point():
x = ['罗志祥道歉','钟南山说疫情挡不住航天豪情','纯电动还是保时捷吗','向往的生活定档','宇宙第一次听见中国声音']
y = [5782383,1981852,1971252,1769837,1447369]
plt.scatter(x,y,color='red', s=25, marker="o")
plt.xlabel("热搜标题")
plt.ylabel("热搜热度")
plt.title("热搜标题与热度散点图")
plt.show()
Scatter_point()
#做出数据前五折线图
def line_diagram():
x = ['罗志祥道歉','钟南山说疫情挡不住航天豪情','纯电动还是保时捷吗','向往的生活定档','宇宙第一次听见中国声音']
y = [5782383,1981852,1971252,1769837,1447369]
plt.xlabel('热搜标题')
plt.ylabel('热搜热度')
plt.plot(x,y)
plt.scatter(x,y)
plt.title("热搜标题与热度折线图")
plt.show()
line_diagram()
file_path="D:\爱剪辑\\wbrs2.xlsx"
#做出数据前五垂直柱状图
plt.rcParams['font.family']=['sans-serif']
plt.rcParams['font.sans-serif']=['SimHei']
plt.bar(['罗志祥道歉','钟南山说疫情挡不住航天豪情','纯电动还是保时捷吗','向往的生活定档','宇宙第一次听见中国声音'], [5782383,1981852,1971252,1769837,1447369])
plt.legend()
plt.xlabel("标题")
plt.ylabel("热搜热度")
plt.title('排名前五热搜')
plt.show()
将数据作图得出的图像进行保存:
plt.savefig(fname="D:/微博热搜前五排行图.jpg",figsize=[1,1])
#保存图像
建立线性回归方程:
import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
from scipy.optimize import leastsq
#导入库读取爬取的数据前5
file_path="D:\爱剪辑\\wbrs2.xlsx"
df=pd.read_excel(file_path,name=['排名','标题与热度'])
df.set_index('排名',inplace=True)
df.head()
print(df.head())
#设置相同的seed,每次生成的随机数相同。如果不设置seed,则每次会生成不同的随机数
np.random.seed(0)
chinese=matplotlib.font_manager.FontProperties(fname='C:\Windows\Fonts\simsun.ttc')
##样本数据(Xi,Yi),需要转换成数组(列表)形式
Xi=np.array([1,2,3,4,5])
Yi=np.array([5782383,1981852,1971252,1769837,1447369])
##需要拟合的函数func :指定函数的形状 k= 0.42116973935 b= -8.28830260655
def fit_func(p,x):
k,b=p
return k*x+b
##偏差函数:x,y都是列表:这里的x,y和样本数据Xi,Yi中是一一对应的
def error_func(p,x,y):
return fit_func(p,x)-y
#k,b的初始值,可以任意设定,但可以调整
p0=[1,20]
#使用leastsq()函数可以很快速地使用最小二乘法对数据进行拟合
Para=leastsq(error_func,p0,args=(Xi,Yi))
#读取结果
k,b=Para[0] #k,b表示什么?
print("k=",k,"b=",b)
#画样本点
plt.figure(figsize=(8,6)) ##指定图像比例: 8:6
plt.scatter(Xi,Yi,color="green",label=u"样本数据",linewidth=2)
#画拟合直线
x=np.linspace(150,190,100) ##在150-190直接画100个连续点
y=k*x+b ##函数式
plt.plot(x,y,color="red",label=u"拟合直线",linewidth=2)
plt.legend(loc=3,prop=chinese) #绘制图例
plt.show()
完整程序代码:
import requests
from bs4 import BeautifulSoup
url='https://s.weibo.com/top/summary?Refer=top_hot&topnav=1&wvr=6'
def getHTMLText(url,timeout=30):
try:
r=requests.get(url,timeout=30)
r.raise_for_status()
r.encoding=r.apparent_encoding
return r.text
except:
return'产生异常'
html=getHTMLText(url)
soup=BeautifulSoup(html,'html.parser')
print(soup.prettify())
#引入所需要到的第三方库
import requests
from bs4 import BeautifulSoup
import pandas as pd
from pandas import DataFrame
import csv
#输入所要爬取的网页
url="https://s.weibo.com/top/summary?Refer=top_hot&topnav=1&wvr=6"
#伪装爬虫头避免被检测拦截
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}
#请求网站
r=requests.get(url)
print(r.text)
#对页面内容重新编码
r.encoding=r.apparent_encoding
data=r.text
#使用BeautifulSoup
soup=BeautifulSoup(data,'html.parser')
#显示网站结构
print(soup.prettify())
#解析网页了解到热搜排名和热搜标题热度分别放在两个class当中,创建两个个空列表
head=[]
index=[]
#把排名添加进空列表
for i in soup.find_all(class_="td-01 rank top"):
head.append(i.get_text().strip())
#把热度标题添加进空列表
for k in soup.find_all(class_="td-02"):
index.append(k.get_text().strip())
data=[head,index]
print(data)
s=pd.DataFrame(data,index=["排名","标题\热度数据"])
#将所得数据进行可视化
print(s.T)
#将数据保存至本地
S="D:\爱剪辑\\wbrs2.xlsx"
df=pd.DataFrame(data,index=["排名","标题\热度数据"])
print(df.T)
df.T.to_excel(S)
#进行数据处理
print(df.isnull())
print(df.duplicated())
print(df.isna().head())
print(df.describe())
titanic=pd.DataFrame(pd.read_excel('D:\爱剪辑\\wbrs2.xlsx'))
titanic.drop_duplicates()
titanic.head()
#将保存至本地的数据加载到DataFrame中
wbrs2_df=pd.read_excel('D:\爱剪辑\\wbrs2.xlsx',sheet_name='Sheet1')
wbrs2_df.head()
wbrs2_df.describe()
#导入作图所需的库
import matplotlib
import pandas as pd
from matplotlib import pyplot as plt
#读取并可视化数据
file_path="D:\爱剪辑\\wbrs2.xlsx"
df=pd.read_excel(file_path,name=['排名','标题','热度数据'])
df.set_index('排名',inplace=True)
df.head()
print(df.head())
#做出数据前五散点图
def Scatter_point():
x = ['罗志祥道歉','钟南山说疫情挡不住航天豪情','纯电动还是保时捷吗','向往的生活定档','宇宙第一次听见中国声音']
y = [5782383,1981852,1971252,1769837,1447369]
plt.scatter(x,y,color='red', s=25, marker="o")
plt.xlabel("热搜标题")
plt.ylabel("热搜热度")
plt.title("热搜标题与热度散点图")
plt.show()
Scatter_point()
#做出数据前五折线图
def line_diagram():
x = ['罗志祥道歉','钟南山说疫情挡不住航天豪情','纯电动还是保时捷吗','向往的生活定档','宇宙第一次听见中国声音']
y = [5782383,1981852,1971252,1769837,1447369]
plt.xlabel('热搜标题')
plt.ylabel('热搜热度')
plt.plot(x,y)
plt.scatter(x,y)
plt.title("热搜标题与热度折线图")
plt.show()
line_diagram()
file_path="D:\爱剪辑\\wbrs2.xlsx"
#做出数据前五垂直柱状图
plt.rcParams['font.family']=['sans-serif']
plt.rcParams['font.sans-serif']=['SimHei']
plt.bar(['罗志祥道歉','钟南山说疫情挡不住航天豪情','纯电动还是保时捷吗','向往的生活定档','宇宙第一次听见中国声音'], [5782383,1981852,1971252,1769837,1447369])
plt.legend()
plt.xlabel("标题")
plt.ylabel("热搜热度")
plt.title('排名前五热搜')
plt.show()
#保存图像
plt.savefig(fname="D:/微博热搜前五排行图.jpg",figsize=[1,1])
#导入所需要的第三方库用于做排名前五与热度的回归方程图
import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
from scipy.optimize import leastsq
#导入库读取爬取的数据前5
file_path="D:\爱剪辑\\wbrs2.xlsx"
df=pd.read_excel(file_path,name=['排名','标题与热度'])
df.set_index('排名',inplace=True)
df.head()
print(df.head())
#设置相同的seed,每次生成的随机数相同。如果不设置seed,则每次会生成不同的随机数
np.random.seed(0)
chinese=matplotlib.font_manager.FontProperties(fname='C:\Windows\Fonts\simsun.ttc')
##样本数据(Xi,Yi),需要转换成数组(列表)形式
Xi=np.array([1,2,3,4,5])
Yi=np.array([5782383,1981852,1971252,1769837,1447369])
##需要拟合的函数func :指定函数的形状 k= 0.42116973935 b= -8.28830260655
def fit_func(p,x):
k,b=p
return k*x+b
##偏差函数:x,y都是列表:这里的x,y和样本数据Xi,Yi中是一一对应的
def error_func(p,x,y):
return fit_func(p,x)-y
#k,b的初始值,可以任意设定,但可以调整
p0=[1,20]
#使用leastsq()函数可以很快速地使用最小二乘法对数据进行拟合
Para=leastsq(error_func,p0,args=(Xi,Yi))
#读取结果
k,b=Para[0] #k,b表示什么?
print("k=",k,"b=",b)
#画样本点
plt.figure(figsize=(8,6)) ##指定图像比例: 8:6
plt.scatter(Xi,Yi,color="green",label=u"样本数据",linewidth=2)
#画拟合直线
x=np.linspace(150,190,100) ##在150-190直接画100个连续点
y=k*x+b ##函数式
plt.plot(x,y,color="red",label=u"拟合直线",linewidth=2)
plt.legend(loc=3,prop=chinese) #绘制图例
plt.show()
结论:经过对主题数据的分析可视化,可以更好地看出热搜数据的体现,更简单快捷地了解到数据,能更好地分析数据。
小结:通过对这次程序设计任务完成的情况,在程序设计的过程中,自己在python的许多方面的应用很生疏,需要多练,在python方面的知识储备不足,导致需要大量的时间才能解决简单的问题。