一、主题式网络爬虫设计方案
1,主题式网络爬虫名称:
爬取爱奇艺影片热榜
2,主题式网络爬虫爬取的内容与数据特征分析:
爬取内容为:影片名称,排名,与其点击量
数据特征分析:将其储存于csv或xlsx文件中
3.主题式网络爬虫设计方案概述(包括实现思路与技术难点)
实现思路:首先进行对网页源代码的访问分析,用BeautifulSoup进行HTML的解析和信息的爬取,后续对爬取下来的信息用pandas进行绘图数据分析
技术难点:爬取信息时对标签的查找,写出查找所需标签的代码,对数据进行相应的分析
二、主题页面的结构特征分析
打开网址http://v.iqiyi.com/index/dianying/index.html,F12或右键点击检查


源代码中可以看到,影片标题的名称在div标签下的a,title-link标签中,点击数在标签div,qy-top-title-zhishu中
用for语句及find_all语句进行遍历和爬取
三、网络爬虫程序设计
#导入所需要的BeautifulSoup和pandas
import requests
import pandas as pd
from bs4 import BeautifulSoup
#待爬取的网址
url = "http://v.iqiyi.com/index/dianying/index.html"
#模拟浏览器
header={"User-Agent": "kaidie"}
#发送请求
r = requests.get(url,headers=header)
#创建标题的空列表
titlelist=[]
#创建点击数的空列表
mathlist=[]
#为储存数据创立空列表
alist=[]
#用BeautifulSoup进行html的解析
html = r.text
soup=BeautifulSoup(html,'html.parser')
#找到所对应的标签
#用for遍历循环find_all查找语句查找标题
for a in soup.find_all("a","title-link"):
titlelist.append(a.string)
#同理找视频的点击数
for div in soup.find_all("div","qy-top-title-zhishu"):
mathlist.append(div.string)
print("-------------------------爱奇艺影片榜前25-------------------------")
print("{:^10}\t{:^30}\t{:^20}".format("排名","电影名","点击数"))
#获取爱奇艺影片榜前25名
for i in range(25):
print("{:^10}\t{:^30}\t{:^20}".format(i+1,titlelist[i],mathlist[i]))
#将获取的数据放入alist的空列表中
for i in range(25):
alist.append([i+1,titlelist[i],mathlist[i]])
#用pandas对数据进行储存,做到数据的持久化
A = pd.DataFrame(alist,columns = ['排名','电影名','点击数'])
A.to_excel('爱奇艺排行.xlsx')


2.对数据进行清洗和处理
#读取文件中的信息
df = pd.DataFrame(pd.read_excel('爱奇艺排行.xlsx'))
#打印出所有的信息
df.head(25)

#根据具体的需求可以清除不需要的数据
df.drop("点击数", axis=1,inplace=True)
df.head(10)

#重复值的处理
df = pd.DataFrame(pd.read_excel('爱奇艺排行.xlsx'))
df.duplicated()

#异常值的观察
df = pd.DataFrame(pd.read_excel('爱奇艺排行.xlsx'))
df.describe()

#查看相关系数
df = pd.DataFrame(pd.read_excel('爱奇艺排行.xlsx'))
df.corr()

3.文本分析
#首先导入做词云所需要的 from wordcloud import WordCloud import matplotlib.pyplot as plt from imageio import imread
#读取爱奇艺排行.xlsx将其中的电影名写到txt文本中去
Name = pd.read_excel("爱奇艺排行.xlsx", encoding='utf-8')
with open("电影名.txt",'a+', encoding='utf-8') as f:
for title in Name.电影名:
f.write((str(title)+'\n'))
#读取电影名.txt文本
text=open('电影名.txt',encoding='utf-8').read()
#词云的背景图片
photo=imread('手牵手.jpg')
Cyun=WordCloud(
background_color = "white",
mask = photo,
width=1600,
repeat=True,
font_path=r'simfang.ttf',
height=1600).generate(text)
plt.imshow(Cyun)
plt.axis("off")
plt.show()
#保存词云图片
Cyun.to_file("爱奇艺词云.jpg")
生成的词云如下

4.数据分析与可视化
#根据画图的需求导入相应的库 from matplotlib import pyplot as plt import numpy as np import matplotlib.pyplot as plt import matplotlib
import seaborn as sns
#定义一个散点图的函数
#排名与点击数的散点图 def Sspot(): df = pd.DataFrame(pd.read_excel('爱奇艺排行.xlsx')) #赋予x,y所对应的值 x = df.排名 y = df.点击数 plt.xlabel("排名") plt.ylabel("点击数") plt.scatter(x,y,color="green",label="散点") plt.title("排名与点击数的散点图") plt.legend() plt.show() Sspot()

#绘制扇形图
def Pspot():
df = pd.DataFrame(pd.read_excel('爱奇艺排行.xlsx'))
x = df.电影名
y = df.点击数
#前五名的电影标题
name = [x[0],x[1],x[2],x[3],x[4]]
math = [y[0],y[1],y[2],y[3],y[4]]
explode=[0.1,0.1,0.1,0.1,0.1]
plt.pie(math,labels=name,colors=["r","g","c","b","y"],explode=explode)
plt.axis("equal")
plt.title("点击数与电影的扇形图")
plt.show()
Pspot()

#排名与点击数的条形图
def Tspot():
df = pd.DataFrame(pd.read_excel('爱奇艺排行.xlsx'))
x = df.排名
y = df.点击数
plt.xlabel("排名")
plt.ylabel("点击数")
plt.bar(x,y,color="green")
plt.title("排名与点击数的条形图")
plt.show()
Tspot()

#前五名的电影与点击数的条形图
def Tspot2():
df = pd.DataFrame(pd.read_excel('爱奇艺排行.xlsx'))
x = df.电影名[:5]
y = df.点击数[:5]
plt.xlabel("电影名")
plt.ylabel("点击数")
plt.bar(x,y,color="green")
plt.title("电影名与点击数的条形图")
plt.show()
Tspot2()

#排名与点击数的折线图
def Zspot():
df = pd.DataFrame(pd.read_excel('爱奇艺排行.xlsx'))
x = df.排名
y = df.点击数
plt.xlabel("排名")
plt.ylabel("点击数")
plt.plot(x,y,color="green",label="折线")
plt.title("排名与点击数的折线图")
plt.legend()
plt.show()
Zspot()

#回归直线的图
def huigui():
#x,y为回归直线的排名和点击数
x = df.排名
y = df.点击数
#X,Y为散点图的
X = df.排名
Y = df.点击数
#先定义所需要的数据
x_i2=0
x_i =0
y_i=0
#计算出x,y的均值用mean()
q = x.mean()
w = y.mean()
for i in range(25):
x_i2 = x_i+x[i]*x[i]
x_i = x_i+x[i]
y_i = y_i+y[i]
#运用回归直线的公式计算出所需要的值
#分子
m_1 = x_i*y_i-25*q*w
#分母
m_2 = x_i2-25*q*q
#斜率
k = m_1/m_2
#截距
b = w-q*k
x=np.linspace(0,25)
y=k*x+b
print("斜率k=",k,"截距b=",b)
plt.figure(figsize=(6,4))
plt.xlabel('排名')
plt.ylabel('点击数')
plt.scatter(X,Y,color="green",label="散点",linewidth=2)
plt.plot(x, y,color="blue",label= "回归直线")
plt.title("回归直线图")
plt.legend()
plt.show()
huigui()

#排名和点击数的线性关系
df = pd.DataFrame(pd.read_excel('爱奇艺排行.xlsx'))
sns.lmplot(x="排名",y= "点击数",data=df)

5.完整程序代码
1 #导入所需要的BeautifulSoup和pandas
2 import requests
3 import pandas as pd
4 from bs4 import BeautifulSoup
5 #根据画图的需求导入相应的库
6 from matplotlib import pyplot as plt
7 import numpy as np
8 import matplotlib.pyplot as plt
9 import matplotlib
10 import seaborn as sns
11 #导入做词云所需要的
12 from wordcloud import WordCloud
13 import matplotlib.pyplot as plt
14 from imageio import imread
15
16 #待爬取的网址
17 url = "http://v.iqiyi.com/index/dianying/index.html"
18 #模拟浏览器
19 header={"User-Agent": "kaidie"}
20 #发送请求
21 r = requests.get(url,headers=header)
22 #创建标题的空列表
23 titlelist=[]
24 #创建点击数的空列表
25 mathlist=[]
26 #为储存数据创立空列表
27 alist=[]
28
29 #用BeautifulSoup进行html的解析
30 html = r.text
31 soup=BeautifulSoup(html,'html.parser')
32 #找到所对应的标签
33 #用for遍历循环find_all查找语句查找标题
34 for a in soup.find_all("a","title-link"):
35 titlelist.append(a.string)
36
37 #同理找视频的点击数
38 for div in soup.find_all("div","qy-top-title-zhishu"):
39 mathlist.append(div.string)
40
41 print("-------------------------爱奇艺影评榜前25-------------------------")
42 print("{:^10}\t{:^30}\t{:^20}".format("排名","电影名","点击数"))
43
44 #获取爱奇艺影评榜前25名
45 for i in range(25):
46 print("{:^10}\t{:^30}\t{:^20}".format(i+1,titlelist[i],mathlist[i]))
47
48 #将获取的数据放入alist的空列表中
49 for i in range(25):
50 alist.append([i+1,titlelist[i],mathlist[i]])
51
52 #用pandas对数据进行储存,做到数据的持久化
53 A = pd.DataFrame(alist,columns = ['排名','电影名','点击数'])
54 A.to_excel('爱奇艺排行.xlsx')
55
56 #读取文件中的信息
57 df = pd.DataFrame(pd.read_excel('爱奇艺排行.xlsx'))
58 #打印出所有的信息
59 df.head(25)
60
61 #根据具体的需求可以清除不需要的数据
62 df.drop("点击数", axis=1,inplace=True)
63 df.head(10)
64
65 #重复值的处理
66 df = pd.DataFrame(pd.read_excel('爱奇艺排行.xlsx'))
67 df.duplicated()
68
69 #异常值的观察
70 df = pd.DataFrame(pd.read_excel('爱奇艺排行.xlsx'))
71 df.describe()
72
73 #查看相关系数
74 df = pd.DataFrame(pd.read_excel('爱奇艺排行.xlsx'))
75 df.corr()
76
77 #排名和点击数的线性关系
78 df = pd.DataFrame(pd.read_excel('爱奇艺排行.xlsx'))
79 sns.lmplot(x="排名",y= "点击数",data=df)
80
81 #读取爱奇艺排行.xlsx将其中的电影名写到txt文本中去
82 Name = pd.read_excel("爱奇艺排行.xlsx", encoding='utf-8')
83 with open("电影名.txt",'a+', encoding='utf-8') as f:
84 for title in Name.电影名:
85 f.write((str(title)+'\n'))
86
87 #读取电影名.txt文本
88 text=open('电影名.txt',encoding='utf-8').read()
89 #词云的背景图片
90 photo=imread('手牵手.jpg')
91 Cyun=WordCloud(
92 background_color = "white",
93 mask = photo,
94 width=1600,
95 repeat=True,
96 font_path=r'simfang.ttf',
97 height=1600).generate(text)
98 plt.imshow(Cyun)
99 plt.axis("off")
100 plt.show()
101 #保存词云图片
102 Cyun.to_file("爱奇艺词云.jpg")
103
104 #定义一个散点图的函数
105 #排名与点击数的散点图
106 def Sspot():
107 df = pd.DataFrame(pd.read_excel('爱奇艺排行.xlsx'))
108 #赋予x,y所对应的值
109 x = df.排名
110 y = df.点击数
111 plt.xlabel("排名")
112 plt.ylabel("点击数")
113 plt.scatter(x,y,color="green",label="散点")
114 plt.title("排名与点击数的散点图")
115 plt.legend()
116 plt.show()
117 Sspot()
118
119 #绘制扇形图
120 def Pspot():
121 df = pd.DataFrame(pd.read_excel('爱奇艺排行.xlsx'))
122 x = df.电影名
123 y = df.点击数
124 #前五名的电影标题
125 name = [x[0],x[1],x[2],x[3],x[4]]
126 math = [y[0],y[1],y[2],y[3],y[4]]
127 explode=[0.1,0.1,0.1,0.1,0.1]
128 plt.pie(math,labels=name,colors=["r","g","c","b","y"],explode=explode)
129 plt.axis("equal")
130 plt.title("排名与电影的扇形图")
131 plt.show()
132 Pspot()
133
134 #排名与点击数的条形图
135 def Tspot():
136 df = pd.DataFrame(pd.read_excel('爱奇艺排行.xlsx'))
137 x = df.排名
138 y = df.点击数
139 plt.xlabel("排名")
140 plt.ylabel("点击数")
141 plt.bar(x,y,color="green")
142 plt.title("排名与点击数的条形图")
143 plt.show()
144 Tspot()
145
146 #前五名的电影与点击数的条形图
147 def Tspot2():
148 df = pd.DataFrame(pd.read_excel('爱奇艺排行.xlsx'))
149 x = df.电影名[:5]
150 y = df.点击数[:5]
151 plt.xlabel("电影名")
152 plt.ylabel("点击数")
153 plt.bar(x,y,color="green")
154 plt.title("电影名与点击数的条形图")
155 plt.show()
156 Tspot2()
157
158 #排名与点击数的折线图
159 def Zspot():
160 df = pd.DataFrame(pd.read_excel('爱奇艺排行.xlsx'))
161 x = df.排名
162 y = df.点击数
163 plt.xlabel("排名")
164 plt.ylabel("点击数")
165 plt.plot(x,y,color="green",label="折线")
166 plt.title("排名与点击数的折线图")
167 plt.legend()
168 plt.show()
169 Zspot()
170
171 #回归直线的图
172 def huigui():
173 #x,y为回归直线的排名和点击数
174 x = df.排名
175 y = df.点击数
176 #X,Y为散点图的
177 X = df.排名
178 Y = df.点击数
179 #先定义所需要的数据
180 x_i2=0
181 x_i =0
182 y_i=0
183 #计算出x,y的均值用mean()
184 q = x.mean()
185 w = y.mean()
186 for i in range(25):
187 x_i2 = x_i+x[i]*x[i]
188 x_i = x_i+x[i]
189 y_i = y_i+y[i]
190 #运用回归直线的公式计算出所需要的值
191 #分子
192 m_1 = x_i*y_i-25*q*w
193 #分母
194 m_2 = x_i2-25*q*q
195 #斜率
196 k = m_1/m_2
197 #截距
198 b = w-q*k
199 x=np.linspace(0,25)
200 y=k*x+b
201 print("斜率k=",k,"截距b=",b)
202 plt.figure(figsize=(6,4))
203 plt.xlabel('排名')
204 plt.ylabel('点击数')
205 plt.scatter(X,Y,color="green",label="散点",linewidth=2)
206 plt.plot(x, y,color="blue",label= "回归直线")
207 plt.title("回归直线图")
208 plt.legend()
209 plt.show()
210 huigui()
四、结论
根据数据的图形分析,点击数会随着排名的降低呈现大幅度的下降,根据点击数的数量差距可以知道他们排名差距程度的多少。
小结:在完成程序的过程,有意外获得的收获也有一些困难,由于一个的函数字母的输入的错误导致代码无法运行,所以要养成写代码检查的习惯。同时通过这次的补考让我对python的应用有了更进一步的提升,受益良多。

