一、主题式网络爬虫设计方案
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的应用有了更进一步的提升,受益良多。