Python爬虫

您所在的位置:网站首页 豆瓣95分以上电影 Python爬虫

Python爬虫

2023-03-17 22:57| 来源: 网络整理| 查看: 265

本文就豆瓣8分以上电影进行爬取-存储-可视化分析。 不足之处欢迎在评论区指出讨论。 当然,如果觉得不错,要帮助的话,还请点个赞。

目录 数据爬取分析网页动态网页和静态网页 获取信息获得二级信息分析动态链接 数据存储存储到CSV文件存储到EXCEL文件 完整爬取代码数据可视化分析评分-年份类别分析出品地区分析

数据爬取 分析网页

爬取网页链接如下: URL:https://movie.douban.com/tag/#/?sort=U&range=8,10&tags=%E7%94%B5%E5%BD%B1 要爬取的网页展示

动态网页和静态网页

在爬取前要先分析网页是动态还是静态的。 动态网页和静态网页的最大区别是:

1.静态页面是不能随时改动的,静态是一次性bai写好放在服务器上进行浏览的,如果想改动,必须在页面上修改,然后再上传服务器覆盖原来的页面,这样才能更新信息,比较麻烦,使用者不能随时修改。

2.动态页面是可以随时改变内容的,有前后台之分,管理员可以在后台随时更新网站的内容,前台页面的内容也会随之更新,比较简单易学。

静态网页是指:

不应用程序而直接或间接制作成html的网页,这种网页的内容是固定的,修改和更新都必须要通过专用的网页制作工具,比如Dreamweaver。

动态网页是指:

使用网页脚本语言,比如php、asp、asp.net等,通过脚本将网站内容动态存储到数据库,用户访问网站是通过读取数据库来动态生成网页的方法。

网站上主要是一些框架基础,网页的内容大都存储在数据库中。 在这里插入图片描述 扩展资料: 动态网页:

1.所谓的动态网页,是指跟静态网页相对的一种网页编程技术。

2.静态网页,随着html代码的生成,页面的内容和显示效果就基本上不会发生变化了,除非你修改页面代码。

3.而动态网页则不然,页面代码虽然没有变,但是显示的内容却是可以随着时间、环境或者数据库操作的结果而发生改变的。

静态网页:

1.在网站设计中,纯粹HTML格式的网页通常被称为“静态网页”,早期的网站一般都是由静态网页制作的。

2.静态网页是相对于动态网页而言,是指没有后台数据库、不含程序和不可交互的网页。

3.你编的是什么它显示的就是什么、不会有任何改变。

4.静态网页相对更新起来比较麻烦,适用于一般更新较少的展示型网站。

观察网页,发现数据是动态加载的,所以这是一个动态网页,那我们就要找到真正显示电影信息的链接。 在这里插入图片描述 检查网页,选中Network-XHR-(ctrl+R)刷新网页。Name中出现的第一个URLhttps://movie.douban.com/j/new_search_subjects?sort=U&range=8,10&tags=%E7%94%B5%E5%BD%B1&start=0就是当前页的链接,点击加载更多时,会出现下一页的URL。

获取信息

请求网页用的是Requests库(Requests 唯一的一个非转基因的 Python HTTP 库,人类可以安全享用)。 注意,header可通过检查网页-刷新-在header的最后找到。 观察可知,我们需要的数据就在一个JSON串里。那么只要将网页用JSON解析后,想要那个数据就可以任我们取了。 比如获得所有电影的名称:

info=r.json() for i in range(20): print(info["data"][i]["title"]) 获得二级信息

从JSON串里,我们可以获得电影的演员列表、封面、导演、评分、名称、URL,如下图所示: 在这里插入图片描述 那么,我们要进一步获取电影的介绍时,就可以直接通过JSON串提供的URL去到电影的详情页。这时,详情页是一个静态网页直接检查网页,如图: 在这里插入图片描述 电影剧情简介是不是就躺在标签里,等我们抱。上代码:

r= requests.get(url, headers = headers) soup=BeautifulSoup(r.text,'lxml') text=soup.find('span',property='v:summary').text

值得注意的是,由于编码不同,解码译码都会出现问题。这里用到如下代码:

text.encode("gbk",'ignore').decode("gbk","ignore") 分析动态链接

至此,对一部电影的数据爬取已经完成了,那么,怎么爬取更多数据呢? 继续分析URL。 Request URL: https://movie.douban.com/j/new_search_subjects?sort=U&range=8,10&tags=%E7%94%B5%E5%BD%B1&start=0 Request URL: https://movie.douban.com/j/new_search_subjects?sort=U&range=8,10&tags=%E7%94%B5%E5%BD%B1&start=20 Request URL: https://movie.douban.com/j/new_search_subjects?sort=U&range=8,10&tags=%E7%94%B5%E5%BD%B1&start=40 观察可知,每一个请求里有20条数据,且URL的变化就在于star=?,而间隔就是20,那么我们要请求的链接就可以写成这样:

urls = ['https://movie.douban.com/j/new_search_subjects?sort=U&range=8,10&tags=%E7%94%B5%E5%BD%B1&start={}'.format(str(i)) for i in range(0,40,20)]

如此一来,就可以访问多条数据了。

数据存储

本文中介绍了两种存储的方法。

存储到CSV文件 ''' 将解析得到的内容(字典格式)逐行写入csv文件 ''' def write_dictionary_to_csv(dict,filename): file_name='{}.csv'.format(filename) with open(file_name, 'a',encoding='utf-8') as f: file_exists = os.path.isfile(filename) w =csv.DictWriter(f, dict.keys(),delimiter=',', quotechar='"', lineterminator='\n',quoting=csv.QUOTE_ALL, skipinitialspace=True) if not file_exists : w.writeheader() w.writerow(dict) print('当前行写入csv成功!') 存储到EXCEL文件

EXCEL相比CSV就是可存储的容量更大。

''' 写入excel 将包含所有数据列表压缩为zip,并写入表格 ''' def wirte_xlsl(filename,data): #创建一个新的excel工作表 work_book = xlwt.Workbook(encoding='utf-8') sheet = work_book.add_sheet('sheet1') #设置表头 sheet.write(0,0,'Rate') sheet.write(0,1,'Title') sheet.write(0,2,'Directors') sheet.write(0,3,'Casts') sheet.write(0,4,'Href') sheet.write(0,5,'Summary') #将data的信息循环写入表中,注意此时行号从1开始 row_num = 1 for d in data: sheet.write(row_num,0,d[0]) sheet.write(row_num,1,d[1]) sheet.write(row_num,2,d[2]) sheet.write(row_num,3,d[3]) sheet.write(row_num,4,d[4]) sheet.write(row_num,5,d[5]) row_num += 1 #将工作表,excel文件,保存到本地路径 work_book.save(filename) 完整爬取代码 # -*- coding: utf-8 -*- ''' 作者:Y 功能:爬取豆瓣评分8分以上电影 版本:v1.0 时间:2020-11-23 ''' import requests import os.path import xlwt import csv from bs4 import BeautifulSoup import json headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36' } ''' 将解析得到的内容(字典格式)逐行写入csv文件 ''' def write_dictionary_to_csv(dict,filename): file_name='{}.csv'.format(filename) with open(file_name, 'a',encoding='utf-8') as f: file_exists = os.path.isfile(filename) w =csv.DictWriter(f, dict.keys(),delimiter=',', quotechar='"', lineterminator='\n',quoting=csv.QUOTE_ALL, skipinitialspace=True) if not file_exists : w.writeheader() w.writerow(dict) print('当前行写入csv成功!') ''' 写入excel 将包含所有数据列表压缩为zip,并写入表格 ''' def wirte_xlsl(filename,data): #创建一个新的excel工作表 work_book = xlwt.Workbook(encoding='utf-8') sheet = work_book.add_sheet('sheet1') #设置表头 sheet.write(0,0,'Rate') sheet.write(0,1,'Title') sheet.write(0,2,'Directors') sheet.write(0,3,'Casts') sheet.write(0,4,'Href') sheet.write(0,5,'Summary') #将data的信息循环写入表中,注意此时行号从1开始 row_num = 1 for d in data: sheet.write(row_num,0,d[0]) sheet.write(row_num,1,d[1]) sheet.write(row_num,2,d[2]) sheet.write(row_num,3,d[3]) sheet.write(row_num,4,d[4]) sheet.write(row_num,5,d[5]) row_num += 1 #将工作表,excel文件,保存到本地路径 work_book.save(filename) ''' 获得二级数据 @return text string 电影简介 ''' def get_con2(url): r= requests.get(url, headers = headers) soup=BeautifulSoup(r.text,'lxml') text=soup.find('span',property='v:summary').text if text==None: return '无' else: return text.encode("gbk",'ignore').decode("gbk","ignore")#.encode("gbk",'ignore').decode("gbk","ignore") ''' 获得一级数据 获得8分以上电影信息 ''' def get_content(urls): #write xlsl #存储list title=[] directors=[] rate=[] href=[] casts=[] text=[] for url in urls: r= requests.get(url, headers = headers) info=r.json() for i in range(20): title.append(info["data"][i]["title"]) directors.append(info["data"][i]["directors"]) rate.append(info["data"][i]["rate"]) href.append(info["data"][i]["url"]) text.append(get_con2(info['data'][i]['url'])) casts.append(info["data"][i]["casts"]) data=zip(rate,title,directors,casts,href,text) wirte_xlsl('豆瓣8分以上电影.xlsx',data) # write csv # for url in urls: # r= requests.get(url, headers = headers) # for i in range(20): # title=r.json()['data'][i]['title'] # directors=r.json()['data'][i]['directors'] # rate=r.json()['data'][i]['rate'] # url=r.json()['data'][i]['url'] # casts=r.json()['data'][i]['casts'] # d={ # 'Title':title, # 'Directors':directors, # 'Rate':rate, # 'Url':url, # 'Casts':casts, # } # print(d) # # 逐行写入csv文件 # write_dictionary_to_csv(d,"douban8") if __name__=='__main__': urls = ['https://movie.douban.com/j/new_search_subjects?sort=U&range=8,10&tags=%E7%94%B5%E5%BD%B1&start={}'.format(str(i)) for i in range(0,40,20)] get_content(urls) print('搜索完成')

存储截图: 存储表格展示

数据可视化分析

豆瓣电影信息不是不变的,本文仅对某一时刻爬取的40条电影数据进行分析。

data=pd.read_csv(r'豆瓣8分以上电影.csv',encoding='utf8') df=pd.DataFrame(data) data=data[0:40] 评分-年份 data.plot.scatter(x='year',y='rate')#散点图

观察评分-年份散点图可知,在评分在8分以上的前40部电影中,1995年期间的电影评分更高,质量较高;1995-2005评分分布在9.2上下;2010-2020的电影评分有向下滑的趋势。总的来看,大部分电影还是在9分以上。 在这里插入图片描述

data.hist()#直方图

分别统计出现评分、年份的次数,其直方图如下: 从直方图中可以更加明显的看出,这40部电影,评分在9.1的最多,年份在2019的最多。 在这里插入图片描述

data['rate'].plot() plt.xlabel('count') plt.ylabel('rate') plt.title('40 movie rating') data['year'].plot() plt.xlabel('count') plt.ylabel('year') plt.title('40 movie-year')

在这里插入图片描述 在这里插入图片描述 柱状图显示评分数据

plt.rcParams['figure.figsize']=[13,8] rate=list(data.rate.unique()) rate=sorted(rate) rate df=pd.DataFrame(rate,columns=['rate']) df['count']=[len(data[data['rate']==8.1]),len(data[data['rate']==8.3]), len(data[data['rate']==8.4]),len(data[data['rate']==8.5]), len(data[data['rate']==8.6]),len(data[data['rate']==8.7]), len(data[data['rate']==8.8]),len(data[data['rate']==8.9]), len(data[data['rate']==9.0]),len(data[data['rate']==9.1]), len(data[data['rate']==9.2]),len(data[data['rate']==9.3]), len(data[data['rate']==9.4]),len(data[data['rate']==9.5]), len(data[data['rate']==9.6]),len(data[data['rate']==9.7])] df plt.rcParams['figure.figsize']=[13,8]#这是这个表的大小 lable=df['rate'].values.tolist()#刻度标签 plt.bar(range(16),df['count'].values.tolist(),width=0.5)#14根柱子,对应值,宽度 #下面两个是x轴,y轴的表是的是啥 plt.ylabel('count',fontsize=15) plt.xlabel("rate",fontsize=15) #每一个柱子代表的城市 plt.xticks(range(16),lable) plt.title('40 movie Rating') plt.show()

在这里插入图片描述 该柱状图能更加清晰的看到评分数据。可见其分布也是呈橄榄球状。

plt.figure(figsize=(6,6)) label=df['rate'].values.tolist() explode=[0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01] plt.pie(x=df['count'].values.tolist(),explode=explode,labels=label,autopct='%1.1f%%') plt.title('Rate') plt.show()

饼图显示: 在这里插入图片描述

类别分析 type=' '.join(data['type'])#转为字符串 type=type.replace(' / ',' ')#去除多余字符 # print(type) typelist=type.split(' ')#切割为列表 t=list(set(typelist))#去除重复项 count=[] for i in t: count.append(typelist.count(i))#统计出现次数 plt.bar(range(len(count)),count,width=0.5) plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams['axes.unicode_minus'] = False plt.xticks(rotation=60) plt.ylabel('计数',fontsize=15) plt.xlabel('类型',fontsize=15) plt.xticks(range(len(t)),t) plt.title('类别喜好情况') plt.show()

在这里插入图片描述 根据柱状图可以看出,剧情片最受欢迎,其次是喜剧、爱情、冒险、奇幻、动画类比较受欢迎。运动、古装、同性、歌舞类比较冷门。 附一张词云图:

df['count']=[] type.count('剧情') font = r'C:\Windows\Fonts\simfang.ttf'#解决中文乱码问题 wc=WordCloud(background_color='white',font_path=font, width=1400, height=1400, margin=2) wc.generate(type) wc.to_file("type.png")

在这里插入图片描述

出品地区分析

在这里插入图片描述 根据柱状图可以看出,美国的电影最受欢迎,其次是英国、中国、加拿大。 附一张词云图: 在这里插入图片描述

以上分析是否有击中你的喜好呢?不同意见欢迎在评论区讨论。 如果觉得不错,还请点个赞,感谢各位父老乡亲!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3