python网络爬虫设计————豆瓣电影top250


选题的背景
为什么要选择此选题?要达到的数据分析的预期目标是什么?
随着经济社会的快速发展,电影作为精神文化产品,得到越来越多人的青睐,人们对电影的评价页也参差不齐,在海量的资源中如何尽快找到符合个人品味的电影,成为观众新的问题。基于Python的数据爬虫技术是目前使用最广泛的方法之一,它能够以最快捷的方式展示用户体验数据,帮助观众进行影片选择。豆瓣电影是著名的电影网站,通过豆瓣电影提供的开放接口大规模地获取电影相关数据。
主题式网络爬虫设计方案
1.主题式网络爬虫名称     豆瓣电影top250
2.主题式网络爬虫爬取的内容与数据特征分析
用Python编写爬虫程序抓取了Top250排行榜的影片榜单信息,爬取电影的短评、评分、评价数量等数据,并结合Pythorn的多个库(Pandas、Numpy、Matplotib),使用Numpy系统存情和处理大型数据,最终通过图表展示出来。网络信息资源充盈的今天,网络信息的获取工作十分重要,该设计的意义在于为用户观影提供决策支持。
3.主题式网络爬虫设计方案概述
本次设计通过request库访问,用BeautifulSoup分析网页结构获取数据,将采集到的数据保存在本地

Htmls 页面解析

网络爬虫程序设计

1.数据爬取与采集

 1 import time
 2 import requests
 3 import re
 4 from openpyxl import workbook  # 写入Excel表所用
 5 from bs4 import BeautifulSoup as bs
 6 from matplotlib import pyplot as plt
 7 import matplotlib
 8 import seaborn as sns
 9 from scipy.optimize import leastsq
10 import numpy as np
11 import scipy as sp
12 import pandas as pd
13 
14 class Top250:
15     def __init__(self):
16         #起始地址
17         self.start_url = 'https://movie.douban.com/top250'
18         #请求头,浏览器模拟
19         self.headers = {
20             'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
21         }
22         #爬取页数
23         self.page_num = 10
24 
25 
26     def get_page_url(self):
27         n = 0 #第一页开始,下标0
28         while n<self.page_num:
29             yield self.start_url+'?start={}&filter='.format(n*25)
30             n += 1
31 
32     def getHtml(self):
33         gu = self.get_page_url() #url生成器
34         for url in gu:
35             html = requests.get(url,headers=self.headers).text
36             yield html
37 
38     def getData(self):
39         gh = self.getHtml() # html源码生成器
40         for html in gh: # html:网页源码
41             soup = bs(html, 'lxml')
42             for info in soup.find_all('div', class_='info'):
43                 c_name = info.find('span',class_='title').text.strip() # 得到电影中文名
44                 message = info.select('div.bd p')[0].text.strip() #得到导演、主演、年份、地区信息
45                 yat = re.search('[0-9]+.*\/?', message).group().split('/') #得到年份、地区、类型信息列表
46                 year,area,type = yat[0],yat[1],yat[2]#得到年份、地区、类型
47                 da = re.search('导演.+\s',message).group().strip()+'...' #得到导演、主演混合信息
48                 director = re.findall('导演:(.+?)\s',da)[0].strip() #得到导演信息
49                 #得到主演信息,不存在时发生异常,进行异常处理
50                 try:
51                     mainActors = re.findall('主演:(.+?)[.,]+',da)[0].strip()
52                 except IndexError:
53                     mainActors = '暂无主演信息'
54                 mark_info = info.find('div',class_='star') #得到评分、评价人数混合信息
55                 score= mark_info.find('span',class_='rating_num').text.strip()#得到评分
56                 count = re.search('[0-9]+',mark_info.select('span')[3].text).group() #得到评价人数
57                 #得到简介,捕捉不存在时的异常
58                 try:
59                     quote = info.select('p.quote span')[0].text.strip()
60                 except IndexError:
61                     quote = '该影片暂时无简介'
62                 yield [c_name,year,area,type,director,mainActors,score,count,quote]
63 
64 
65     def saveToExcel(self,file_name):
66         wb = workbook.Workbook()  # 创建Excel对象
67         ws = wb.active  # 获取当前正在操作的表对象
68         ws.append(['电影名', '年份', '地区', '剧情类型', '导演', '主演', '评分', '评论人数', '简介'])
69         gd = self.getData() #数据生成器
70         for data in gd:
71             ws.append(data)
72         wb.save(file_name)
73 
74 if __name__ == '__main__':
75     start = time.time()
76     top = Top250()
77     try:
78         top.saveToExcel('top250.xlsx')
79         print('抓取成功,用时%4.2f'%(time.time()-start)+'')
80     except Exception as e:
81         print('抓取失败,原因:%s'%e)

2.对数据进行清洗和处理

 1 df = pd.DataFrame(pd.read_excel('top250.xlsx'),columns=['排名','电影名', '年份', '地区', '剧情类型', '导演', '主演', '评分', '评论人数', '简介'])
 2 print(df.head())
 3 # 读取excel文件
 4 
 5 
 6 print(df.head())
 7 # 删除无效行与列
 8 
 9 print(df.isnull().sum())
10 # 返回0,表示没有空值
11 print(df.isna().head())
12 # 统计缺失值
13 print(df.isna().head())
14 # 查找重复值

3.数据分析与可视化

1 x = df.排名
2 y = df['评分'][:250]
3 plt.xlabel('评分')
4 plt.ylabel('排名')
5 plt.bar(x,y)
6 plt.title("排名与评分比较图")
7 plt.show()
8 #柱状图

 

1 x = df.排名
2 y = df['评分'][:250]
3 plt.xlabel('排名')
4 plt.ylabel('评分')
5 plt.plot()
6 plt.scatter(x,y)
7 plt.title("排名与评分比较图")
8 plt.show()
9 #散点图

1 sns.lmplot(x='排名',y='评分',data=df)
2 #线性图

 

4.回归方程

 1 X=df.loc[:,'排名']
 2 Y=df.loc[:,'评分']
 3 def func(params,x):
 4     a,b,c=params
 5     return a*x*x+b*x+c
 6 def error_func(params,x,y):
 7     return func(params,x)-y
 8 P0=[1,9.0]
 9 def main():
10     plt.figure(figsize=(8,6))
11     P0=[1,9.0,1]
12     Para=leastsq(error_func,P0,args=(X,Y))
13     a,b,c=Para[0]
14     print("a=",a, "b=",b, "c=",c)
15     plt.scatter(X,Y,color="green",label="样本数据",linewidth=2)
16     x=np.linspace(1,250,40)
17     y=a*x*x+b*x+c
18     plt.plot(x,y,color="red",label="拟合曲线",linewidth=2)
19     plt.xlabel('排名')
20     plt.ylabel('得分')
21     plt.title("排名与得分回归方程")
22     plt.grid()
23     plt.legend()
24     plt.show()
25 main()

5.完整代码

  1 import time
  2 import requests
  3 import re
  4 from openpyxl import workbook  # 写入Excel表所用
  5 from bs4 import BeautifulSoup as bs
  6 from matplotlib import pyplot as plt
  7 import matplotlib
  8 import seaborn as sns
  9 from scipy.optimize import leastsq
 10 import numpy as np
 11 import scipy as sp
 12 import pandas as pd
 13 
 14 class Top250:
 15     def __init__(self):
 16         #起始地址
 17         self.start_url = 'https://movie.douban.com/top250'
 18         #请求头,浏览器模拟
 19         self.headers = {
 20             'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
 21         }
 22         #爬取页数
 23         self.page_num = 10
 24 
 25 
 26     def get_page_url(self):
 27         n = 0 #第一页开始,下标0
 28         while n<self.page_num:
 29             yield self.start_url+'?start={}&filter='.format(n*25)
 30             n += 1
 31 
 32     def getHtml(self):
 33         gu = self.get_page_url() #url生成器
 34         for url in gu:
 35             html = requests.get(url,headers=self.headers).text
 36             yield html
 37 
 38     def getData(self):
 39         gh = self.getHtml() # html源码生成器
 40         for html in gh: # html:网页源码
 41             soup = bs(html, 'lxml')
 42             for info in soup.find_all('div', class_='info'):
 43                 c_name = info.find('span',class_='title').text.strip() # 得到电影中文名
 44                 message = info.select('div.bd p')[0].text.strip() #得到导演、主演、年份、地区信息
 45                 yat = re.search('[0-9]+.*\/?', message).group().split('/') #得到年份、地区、类型信息列表
 46                 year,area,type = yat[0],yat[1],yat[2]#得到年份、地区、类型
 47                 da = re.search('导演.+\s',message).group().strip()+'...' #得到导演、主演混合信息
 48                 director = re.findall('导演:(.+?)\s',da)[0].strip() #得到导演信息
 49                 #得到主演信息,不存在时发生异常,进行异常处理
 50                 try:
 51                     mainActors = re.findall('主演:(.+?)[.,]+',da)[0].strip()
 52                 except IndexError:
 53                     mainActors = '暂无主演信息'
 54                 mark_info = info.find('div',class_='star') #得到评分、评价人数混合信息
 55                 score= mark_info.find('span',class_='rating_num').text.strip()#得到评分
 56                 count = re.search('[0-9]+',mark_info.select('span')[3].text).group() #得到评价人数
 57                 #得到简介,捕捉不存在时的异常
 58                 try:
 59                     quote = info.select('p.quote span')[0].text.strip()
 60                 except IndexError:
 61                     quote = '该影片暂时无简介'
 62                 yield [c_name,year,area,type,director,mainActors,score,count,quote]
 63 
 64 
 65     def saveToExcel(self,file_name):
 66         wb = workbook.Workbook()  # 创建Excel对象
 67         ws = wb.active  # 获取当前正在操作的表对象
 68         ws.append(['电影名', '年份', '地区', '剧情类型', '导演', '主演', '评分', '评论人数', '简介'])
 69         gd = self.getData() #数据生成器
 70         for data in gd:
 71             ws.append(data)
 72         wb.save(file_name)
 73 
 74 if __name__ == '__main__':
 75     start = time.time()
 76     top = Top250()
 77     try:
 78         top.saveToExcel('top250.xlsx')
 79         print('抓取成功,用时%4.2f'%(time.time()-start)+'')
 80     except Exception as e:
 81         print('抓取失败,原因:%s'%e)
 82 
 83 df = pd.DataFrame(pd.read_excel('top250.xlsx'),columns=['排名','电影名', '年份', '地区', '剧情类型', '导演', '主演', '评分', '评论人数', '简介'])
 84 print(df.head())
 85 # 读取excel文件
 86 
 87 
 88 print(df.head())
 89 # 删除无效行与列
 90 
 91 print(df.isnull().sum())
 92 # 返回0,表示没有空值
 93 print(df.isna().head())
 94 # 统计缺失值
 95 print(df.isna().head())
 96 # 查找重复值
 97 
 98 from matplotlib import pyplot as plt
 99 import matplotlib
100 import seaborn as sns
101 from scipy.optimize import leastsq
102 
103 import numpy as np
104 import scipy as sp
105 import pandas as pd
106 
107 x = df.排名
108 y = df['评分'][:250]
109 plt.xlabel('评分')
110 plt.ylabel('排名')
111 plt.bar(x,y)
112 plt.title("排名与评分比较图")
113 plt.show()
114 #柱状图
115 
116 
117 x = df.排名
118 y = df['评分'][:250]
119 plt.xlabel('排名')
120 plt.ylabel('评分')
121 plt.plot()
122 plt.scatter(x,y)
123 plt.title("排名与评分比较图")
124 plt.show()
125 #散点图
126 
127 sns.lmplot(x='排名',y='评分',data=df)
128 #线性图
129 
130 X=df.loc[:,'排名']
131 Y=df.loc[:,'评分']
132 def func(params,x):
133     a,b,c=params
134     return a*x*x+b*x+c
135 def error_func(params,x,y):
136     return func(params,x)-y
137 P0=[1,9.0]
138 def main():
139     plt.figure(figsize=(8,6))
140     P0=[1,9.0,1]
141     Para=leastsq(error_func,P0,args=(X,Y))
142     a,b,c=Para[0]
143     print("a=",a, "b=",b, "c=",c)
144     plt.scatter(X,Y,color="green",label="样本数据",linewidth=2)
145     x=np.linspace(1,250,40)
146     y=a*x*x+b*x+c
147     plt.plot(x,y,color="red",label="拟合曲线",linewidth=2)
148     plt.xlabel('排名')
149     plt.ylabel('得分')
150     plt.title("排名与得分回归方程")
151     plt.grid()
152     plt.legend()
153     plt.show()
154 main()

经过对主题数据的分析与可视化可以让数据以更生动形象具体的方式呈现在我们眼前

在完成此设计过程中发现通过Chrome浏览器对于写爬虫非常有用,Chrome自带的开发者工具能帮助分析网页的源码、资源和数据包。特别是要写表单提交一类功能时,Chrome自带的抓包功能非常好用,通过分析包结构可以实现各类复杂表单的模拟提交。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM