一.主题式网络主题式网络爬虫设计方案
1.爬虫名称:爬取哔哩哔哩番剧排行榜
2.爬取内容:爬取番剧名称、播放量、评论数、喜欢人数、综合得分。爬取网站:"https://www.bilibili.com/ranking/bangumi/13/0/3"
3.网络爬虫设计方案概述:
思路:通过分析网页源代码,找出数据所在的标签,通过爬虫读取数据保存到csv文件中,读取文件,对数据进行清洗和处理,数据分析与可视化处理。
技术难点:信息处理知识掌握不够全面以及在同一标签下信息的分离
通过命名将混合在一起的三个数据分散开
在将文件进行以csv形式保存并清洗数据
二、主题页面的结构特征分析
打开F12进行寻找我们需要的信息,发现要爬取数据都分布在标签div class “info”里面。播放量、评论数、喜欢人数都在span class "data-box"里面,综合得分在div class "pts"里面
1.主题页面的结构和特征分析:
2.Htmls页面解析
3.节点(标签)查找方法与遍历方法
三、网络爬虫程序设计
全部代码
1 import numpy as np 2 import matplotlib.pyplot as plt 3 import matplotlib as mpl 4 from scipy.optimize import leastsq 5 import requests 6 from bs4 import BeautifulSoup 7 import pandas as pd 8 import csv 9 import jieba 10 import wordcloud 11 import requests 12 from bs4 import BeautifulSoup 13 import pandas as pd 14 15 16 url="https://www.bilibili.com/ranking/bangumi/13/0/3"#哔哩哔哩番剧排行榜 17 #伪装爬虫 18 headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)Chrome/69.0.3497.100 Safari/537.36'} 19 20 #请求网站 21 r=requests.get(url) 22 23 r.encoding=r.apparent_encoding 24 25 #获取源代码 26 x=r.text 27 28 #构造Soup的对象 29 soup=BeautifulSoup(x,'lxml') 30 31 #进行信息的分离 32 a=[] 33 b=[] 34 s=[] 35 d=[] 36 e=[] 37 38 one=soup.find_all(class_="title") 39 40 for i in range(20): 41 a.append(one[i].text) 42 43 44 two=soup.find_all(class_="data-box") 45 46 for i in range(0,60,3): 47 b.append(two[i].text) 48 for i in range(1,60,3): 49 s.append(two[i].text) 50 for i in range(2,60,3): 51 d.append(two[i].text) 52 53 three=soup.find_all(class_="pts") 54 for i in range(20): 55 e.append(three[i].text) 56 57 lt=[] 58 for i in range(20): 59 lt.append([a[i],b[i],s[i],d[i],e[i]]) 60 61 h=pd.DataFrame(lt,columns=["番剧名称","播放量","评论数","喜欢人数","综合得分"]) 62 63 #print(h) 64 65 #保存文件,数据持久化 66 h.to_csv('哔哩哔哩番剧排行榜.csv') 67 68 df = pd.DataFrame(pd.read_csv('哔哩哔哩番剧排行榜.csv')) 69 70 #print(df) 71 df.head() 72 73 df.drop('评论数',axis=1,inplace=True) 74 75 df.drop('番剧名称',axis=1,inplace=True) 76 77 df.drop('综合得分',axis=1,inplace=True) 78 79 df.head() 80 81 #检查是否有重复值 82 df.duplicated() 83 84 #缺失值处理 85 df[df.isnull().values==True]#返回无缺失值 86 87 #用describe()命令显示描述性统计指标 88 df.describe() 89 90 plt.rcParams['axes.unicode_minus']=False #用来正常显示负号 91 92 plt.bar(df.播放量, df.喜欢人数, label="柱状图") 93 94 plt.xlabel("播放量") 95 96 plt.ylabel("喜欢人数") 97 plt.title('播放量与喜欢人数柱状图') 98 plt.show() 99 100 101 102 #绘制散点图 103 def scatter(): 104 plt.scatter(df.喜欢人数, df.播放量, color='green', s=25, marker="o") 105 plt.xlabel("喜欢人数") 106 plt.ylabel("播放量") 107 plt.title("排名与评分散点图") 108 plt.show() 109 scatter() 110 111 112 #绘制折线图 113 def line_diagram(): 114 x = df['播放量'] 115 y = df['喜欢人数'] 116 plt.xlabel('播放量') 117 plt.ylabel('喜欢人数') 118 plt.plot(x,y) 119 plt.scatter(x,y) 120 plt.title("播放量与喜欢人数折线图") 121 plt.show() 122 line_diagram() 123 124 #绘制箱体图 125 import pandas as pd 126 127 from matplotlib import pyplot as plt 128 129 import seaborn as sns 130 131 plt.rcParams['font.sans-serif']=['STSong'] 132 133 file_path = "哔哩哔哩番剧排行榜.csv" 134 135 df = pd.DataFrame(pd.read_csv(file_path,names=["番剧名称","播放量","评论数","喜欢人数","综合得分"])) 136 137 plt.figure(figsize=(10, 8)) 138 139 plt.title('播放量与喜欢人数箱体图') 140 141 sns.boxplot(x='q播放量',y='喜欢人数', data=df) 142 143 144 #绘制一元一次回归方程 145 146 def main(): 147 colnames = ["番剧名称","播放量","评论数","喜欢人数","综合得分"] 148 df = pd.read_csv('哔哩哔哩番剧排行榜.csv',skiprows=1,names=colnames) 149 X = df.播放量 150 Y = df.喜欢人数 151 152 def func(p, x): 153 k, b = p 154 return k * x + b 155 156 def error_func(p, x, y): 157 return func(p,x)-y 158 159 p0 = [0,0] 160 #使用leastsq()函数对数据进行拟合 161 Para = leastsq(error_func, p0, args = (X, Y)) 162 k, b = Para[0] 163 print("k=",k,"b=",b) 164 165 plt.figure(figsize=(10,6)) 166 plt.scatter(X,Y,color="green",label=u"评分分布",linewidth=2) 167 x=np.linspace(0,30,30) 168 y=k*x+b 169 plt.plot(x,y,color="red",label=u"回归方程直线",linewidth=2) 170 171 plt.title("播放量与喜欢人数关系图") 172 plt.xlabel('播放量') 173 plt.ylabel('喜欢人数') 174 plt.legend() 175 plt.show() 176 177 178 main() 179 180 181 #绘制一元二次回归方程 182 def main2(): 183 colnames = ["番剧名称","播放量","评论数","喜欢人数","综合得分"] 184 df = pd.read_csv('哔哩哔哩番剧排行榜.csv',skiprows=1,names=colnames) 185 186 X = df.排名 187 Y = df.评分 188 r=sts.pearsonr(X,Y) #相关性r 189 print('相关性r',r) 190 def func(p, x): 191 a, b, c = p 192 return a * x * x + b * x + c 193 194 def error_func(p, x, y): 195 return func(p,x)-y 196 197 p0 = [0,0,0] 198 199 #使用leastsq()函数对数据进行拟合 200 Para = leastsq(error_func, p0, args = (X, Y)) 201 a, b, c = Para[0] 202 print("a=", a,"b=", b,"c=", c) 203 204 plt.figure(figsize=(10,6)) 205 plt.scatter(X,Y,color="green",label=u"评分分布",linewidth=2) 206 207 x = np.linspace(0,30,30) 208 y = a * x * x + b * x + c 209 210 plt.plot(x,y,color="red",label=u"一元二次回归方程直线",linewidth=2) 211 plt.title("播放量和喜欢人数关系图") 212 plt.xlabel('播放量') 213 plt.ylabel('喜欢人数') 214 plt.legend() 215 plt.show() 216 217 218 main2()