一、主题式网络爬虫设计方案
1.主题式网络爬虫名称:360影视排行榜-总榜爬取
2.主题式网络爬虫爬取的内容:爬取360影视排行榜-总榜的排名、作品名称和昨日指数(前十五)
3.主题式网络爬虫设计方案概述:
先确定想要爬取的网页以及内容,用requests库访问页面用get方法获取页面资源,后登陆网页,通过网页审查元素对页面HTML进行分析,分析完成后用beautifulsoup库获取并提取所要爬的内容信息,最后保存到CSV文件中,并进行数据清洗,数据分析及可视化,绘制图表,数据拟合分析。
二、主题页面的结构特征分析
我们需要爬作品的内容和昨日热度指数,通过浏览页面审查元素,箭头定位查找发现
作品内容的名称隐藏在
标签的中,通过查找多个作品内容发现
页面的所有内容名称全部都在
标签中,向下检索发现内容的具体位置都在子标签的string属性中,可以通过beautiful soup 库实现信息提取
同理 定位多个昨日热度指数的标签位置
发现所有昨日热度指数全部都在
的子标签 中可以根据这些位置开始书写代码。三、网络爬虫程序设计
1.数据爬取与采集
importrequestsfrom bs4 importBeautifulSoupimportbs4importpandas as pdfrom pandas importDataFrame
url= 'https://www.360kan.com/rank/general'
#爬虫请求头信息
headers ={'User-Agent': 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
}#定义函数获取并检测页面信息
defText(url):try:
respone= requests.get(url,headers=headers,timeout=30)
respone.raise_for_status()#解决中文字符编码问题
respone.encoding =respone.apparent_encodingreturnrespone.textexcept:return ""html=Text(url)#使用BeautifulSoup解析页面信息
soup = BeautifulSoup(html, "html.parser")#开始获取作品名称信息
mingzi = soup.find_all('p',class_ = 'm-title')
name=[]for x inmingzi:
name.append(x.string)#使用列表方式 添加信息#获取作品昨日指数信息
zhi = soup.find_all("li",class_='m-item-playcount')
zhishu=[]for y inzhi:
zhishu.append(y.span.string)#使用中文字符的空格填充
print("{}\t{}\t{:^40}".format("排名","作品名称","昨日指数",chr(12288)))#构建填充文件信息所需要的列表
xingxi =[]#用range函数获取前15个数据
for i in range(15):print("{}\t{}\t{:^40}".format(i+1, name[i], zhishu[i],chr(12288)))
xingxi.append([i+1, name[i], zhishu[i]])#生成csv文件
df= pd.DataFrame(xingxi,columns = ['排名','作品内容','昨日指数'])
df.to_csv('yingshi.csv')
输出结果截图:
生成文件截图:
2、对数据进行清洗和处理
(1)
#输出信息检验文件是否成功生成
df = pd.DataFrame(pd.read_csv('yingshi.csv'))print(df)
(2)
#删除无效列
df.drop('作品内容', axis = 1, inplace=True)
df.head()
(3)
#查找重复值
df.duplicated()
(4)
#删除重复值
df =df.drop_duplicates()
df.head()
(5)
#统计昨日指数和排名的空值的个数
df['昨日指数'].isnull().value_counts()
df['排名'].isnull().value_counts()
(6)
#使用describe查看统计信息
df.describe()
(7)
#数据分析
from sklearn.linear_model importLinearRegression
X= df.drop("昨日指数",axis=1)
predict_model=LinearRegression()
predict_model.fit(X,df['排名'])print("回归系数为:",predict_model.coef_)
3、数据分析与可视化
(1)
#绘制柱状图
importpandas as pdimportnumpy as npimportmatplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.bar(df.排名, df.昨日指数, color='purple',alpha=0.3)
plt.xlabel("排名")
plt.ylabel("昨日指数")
plt.title('排名与昨日指数数据柱状图')
plt.show()
(2)
#绘制折线图
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.plot(df.排名, df.昨日指数, color='purple',alpha=0.3)
plt.xlabel("排名")
plt.ylabel("昨日指数")
plt.title('排名与昨日指数数据柱状图')
plt.show()
(3)
#绘制散点图
importmatplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #用于正常显示中文标签#设置散点大小 便于数据观察
size =25plt.scatter(df.排名,df.昨日指数,size, color="purple",alpha=0.5, marker='o')#设置透明度
plt.title("排名与昨日指数散点图")
(4)
#绘制盒图
importseaborn as snsdefbox():
plt.title('昨日指数盒图')
sns.boxplot(x='排名',y='昨日指数', data=df)
box()
(5)
#绘制直方图#设置画布大小
plt.figure(dpi=100)
zhishu=df.昨日指数
paiming=df.排名
plt.bar(zhishu,paiming,color='purple')
plt.title("昨日指数直方图")
plt.xlabel("排名")
plt.ylabel("昨日指数")
plt.show()
(6)
#绘制分布图#设置间距大小
data = {'a': 10, 'b': 15, 'c': 5, 'd': 20}
names=df.昨日指数
values=df.排名
fig, axs= plt.subplots(1, 3, figsize=(9, 3), sharey=True)
axs[0].bar(names, values)
axs[1].scatter(names, values)
axs[2].plot(names, values)
fig.suptitle('Categorical Plotting')
4.根据数据之间的关系,分析两个变量之间的相关系数,画出散点图,并建立变量之间的回归方程
importmatplotlib.pyplot as pltfrom scipy.optimize importleastsqimportnumpy as np#建立排名与昨日指数的回归方程进行回归分析#一元一次回归散点图
X=df.排名
Y=df.昨日指数#生成一元一次方程
deffunc(p,x):
k, b=preturn k * x +bdeferror(p,x,y):return func(p,x)-y#定义一个主函数
defmain():
plt.figure(figsize=(10,6))
p0=[0,0]
Para= leastsq(error,p0,args=(X,Y))
k, b=Para[0]
plt.scatter(X,Y,color="blue",linewidth=2)
x=np.linspace(0,20,20)
y=k * x +b
plt.plot(x,y,color="blue",linewidth=2,)
plt.title("昨日指数值分布")
plt.grid()
plt.show()print(main())
5.将以上各部分的代码汇总,附上完整程序代码
importrequestsfrom bs4 importBeautifulSoupimportbs4importpandas as pdfrom pandas importDataFrame
url= 'https://www.360kan.com/rank/general'
#爬虫请求头信息
headers ={'User-Agent': 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
}#定义函数获取并检测页面信息
defText(url):try:
respone= requests.get(url,headers=headers,timeout=30)
respone.raise_for_status()#解决中文字符编码问题
respone.encoding =respone.apparent_encodingreturnrespone.textexcept:return ""html=Text(url)#使用BeautifulSoup解析页面信息
soup = BeautifulSoup(html, "html.parser")#开始获取作品名称信息
mingzi = soup.find_all('p',class_ = 'm-title')
name=[]for x inmingzi:
name.append(x.string)#使用列表方式 添加信息#获取作品昨日指数信息
zhi = soup.find_all("li",class_='m-item-playcount')
zhishu=[]for y inzhi:
zhishu.append(y.span.string)#使用中文字符的空格填充
print("{}\t{}\t{:^40}".format("排名","作品名称","昨日指数",chr(12288)))#构建填充文件信息所需要的列表
xingxi =[]#用range函数获取前15个数据
for i in range(15):print("{}\t{}\t{:^40}".format(i+1, name[i], zhishu[i],chr(12288)))
xingxi.append([i+1, name[i], zhishu[i]])#生成csv文件
df= pd.DataFrame(xingxi,columns = ['排名','作品内容','昨日指数'])
df.to_csv('yingshi.csv')#输出信息检验文件是否成功生成
df = pd.DataFrame(pd.read_csv('yingshi.csv'))print(df)#删除无效列
df.drop('作品内容', axis = 1, inplace=True)
df.head()#查找重复值
df.duplicated()#删除重复值
df =df.drop_duplicates()
df.head()#统计昨日指数和排名的空值的个数
df['昨日指数'].isnull().value_counts()
df['排名'].isnull().value_counts()#使用describe查看统计信息
df.describe()#数据分析
from sklearn.linear_model importLinearRegression
X= df.drop("昨日指数",axis=1)
predict_model=LinearRegression()
predict_model.fit(X,df['排名'])print("回归系数为:",predict_model.coef_)#绘制柱状图
importpandas as pdimportnumpy as npimportmatplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.bar(df.排名, df.昨日指数, color='purple',alpha=0.3)
plt.xlabel("排名")
plt.ylabel("昨日指数")
plt.title('排名与昨日指数数据柱状图')
plt.show()#绘制折线图
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.plot(df.排名, df.昨日指数, color='purple',alpha=0.3)
plt.xlabel("排名")
plt.ylabel("昨日指数")
plt.title('排名与昨日指数数据柱状图')
plt.show()#绘制散点图
importmatplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #用于正常显示中文标签#设置散点大小 便于数据观察
size =25plt.scatter(df.排名,df.昨日指数,size, color="purple",alpha=0.5, marker='o')#设置透明度
plt.title("排名与昨日指数散点图")#绘制盒图
importseaborn as snsdefbox():
plt.title('昨日指数盒图')
sns.boxplot(x='排名',y='昨日指数', data=df)
box()#绘制直方图#设置画布大小
plt.figure(dpi=100)
zhishu=df.昨日指数
paiming=df.排名
plt.bar(zhishu,paiming,color='purple')
plt.title("昨日指数直方图")
plt.xlabel("排名")
plt.ylabel("昨日指数")
plt.show()#绘制分布图#设置间距大小
data = {'a': 10, 'b': 15, 'c': 5, 'd': 20}
names=df.昨日指数
values=df.排名
fig, axs= plt.subplots(1, 3, figsize=(9, 3), sharey=True)
axs[0].bar(names, values)
axs[1].scatter(names, values)
axs[2].plot(names, values)
fig.suptitle('Categorical Plotting')importmatplotlib.pyplot as pltfrom scipy.optimize importleastsqimportnumpy as np#建立排名与昨日指数的回归方程进行回归分析#一元一次回归散点图
X=df.排名
Y=df.昨日指数#生成一元一次方程
deffunc(p,x):
k, b=preturn k * x +bdeferror(p,x,y):return func(p,x)-y#定义一个主函数
defmain():
plt.figure(figsize=(10,6))
p0=[0,0]
Para= leastsq(error,p0,args=(X,Y))
k, b=Para[0]
plt.scatter(X,Y,color="blue",linewidth=2)
x=np.linspace(0,20,20)
y=k * x +b
plt.plot(x,y,color="blue",linewidth=2,)
plt.title("昨日指数值分布")
plt.grid()
plt.show()print(main())
四、结论1.经过对主题数据的分析与可视化,可以得到哪些结论?
经过这次对主题数据的分析与可视化,我发现对于不同类型的网站的网页分析不同,但是基本上的方法都类似。通过对数据的分析与可视化,加强对数据的掌握,对数据的处理也可以使其更加清晰,更直观的体现数据的本身。
2.对本次程序设计任务完成的情况做一个简单的小结。
小结:本次程序设计任务,对于我们是一个很好的锻炼。既是对之前课程的复习与运用,也是对我们掌握的实质的考察与补充。我也对之前的课程进行了一个复习,也找到了很多自我的短板和遗漏的知识点,也在不断的探索中学习到更多新东西,了解到其实还有很多值得我们去学习,也提高了我对Python的兴趣。