Python爬取猫眼电影TOP100的电影数据(爬取代码+数据可视化分析)

本文主要是爬取猫眼电影TOP100的电影数据,并且进行了跨页爬虫,获取的字段:电影名,主演,上映时间,评分,电影类型和时长。最后保存在csv文件中。然后对爬取的数据进行可视化和数据分析。
如果有什么不足之处,欢迎大家进行评论,我也会进行改正!

目录

  • 数据爬取
    • 反爬虫程序
    • 分析网页链接
    • 获取当前网页信息
    • 获取二级信息
  • 数据存储
  • 完整代码
  • 数据可视化分析
    • 查看CSV文件的数据
    • 查看重复值
    • 删除无意义的列(或行)
    • 上映年份和评分信息可视化
    • 类型信息可视化
    • 国家信息可视化

数据爬取

获取想要的数据是我们进行数据分析的第一步,也是最重要的一步。爬取数据主要分为分析网页、获取数据网页信息、数据存储等几步。
下面博主将会对猫眼电影TOP100的电影数据进行分析爬取。

反爬虫程序

在定义爬虫程序的时候,因为有些网页会有反爬虫的设置,所以在爬虫程序运行过程中会出现问题,因此在爬虫程序中需要添加一个头部 headers 信息,模拟成浏览器访问网页的形式,headers 头部信息中包含 User-Agent 以及 Cookies 等信息。
User-Agent 可以用来判断是否是浏览器发起的 Request,是一个特殊的字符串头,可以识别客户使用的操作系统及浏览器版本等信息。对于 User-Agent 的设置方法有两种,一是自定义 User-Agent 的数组,然后使用 random 的方式随机调用 User-Agent 数组;二是使用 Python 的第三方类库 fake-useragent,它里面提供了很多的 User-Agent,使用时只需要只需要导入第三方库,然后通过 UserAgent().random 获取即可,不用担心重复的问题。使用 fake_useragent 类库首先需要在命令行通过 pip 提前安装该类库然后进行使用。Cookies 是某些网站为了进行 session 跟踪、辨别用户身份而储存在用户本地终端上的数据,通过使用 requests.session()得到 Cookies 信息。

headers = {
     
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
}
res = requests.get(url,headers=headers)
html = etree.HTML(res.text)

分析网页链接

爬取网页的URL为:https://maoyan.com/board/4?
首先要在浏览器中打开网页,并且观察网页信息:

大家可以看到,在该排行榜中,每页显示十个电影的数据信息,100个电影分为十页进行显示,要爬取TOP100排行榜上的全部电影信息,需要10个网址链接,分别为:
https://maoyan.com/board/4?offset=0
https://maoyan.com/board/4?offset=10
https://maoyan.com/board/4?offset=20
https://maoyan.com/board/4?offset=30
https://maoyan.com/board/4?offset=40
https://maoyan.com/board/4?offset=50
https://maoyan.com/board/4?offset=6
https://maoyan.com/board/4?offset=70
https://maoyan.com/board/4?offset=80
https://maoyan.com/board/4?offset=90
由这十个网页大家可以发现每页网址的前面部分都是一样的,只有offset=的数字不一样,但是其实是有规律的,即每页网址最后的数字是递增的(前一个数据+10就是后一个数字),每次请求中都有10条数据。
想要访问多条网址链接,就需将URL中的offset=?进行变化,对网页网址链接进行获取跳转的代码如下所示:

urls = ['http://maoyan.com/board/4?offset={}'.format(str(i)) for i in range(0, 100, 10)]
    for url in urls:
        get_url(url)

获取当前网页信息

在当前网页中,我们需要获取的数据信息是电影名,主演,上映时间,评分。
获取网页中的数据信息,我们就要分析网页的源代码,在浏览器中把要访问的网页打开,然后按下键盘上的F12,就可以查看网页的源代码;也可以单击鼠标右键,然后点击审查元素查看网页源代码。
该网页的源代码如下图所示:
Python爬取猫眼电影TOP100的电影数据(爬取代码+数据可视化分析)_第1张图片
Python爬取猫眼电影TOP100的电影数据(爬取代码+数据可视化分析)_第2张图片
由这两张图片我们可以看到,猫眼电影TOP100中的电影数据信息在网页源代码中的标签是相同的,故在爬取时使用一个for循环即可对全部电影的数据信息进行爬取。
博主在爬取数据时,采用的是xpath方法获取电影数据数据信息,代码如下所示:

def get_url(url):
    res = requests.get(url,headers=headers)
    html = etree.HTML(res.text)
    infos = html.xpath('//dl[@class="board-wrapper"]/dd')
    for info in infos:
        name = info.xpath('div/div/div[1]/p[1]/a/text()')[0]
        info_url = 'http://maoyan.com' + info.xpath('div/div/div[1]/p[1]/a/@href')[0]
        star = info.xpath('div/div/div[1]/p[2]/text()')[0].strip()
        release_time = info.xpath('div/div/div[1]/p[3]/text()')[0].strip()
        score_1 = info.xpath('div/div/div[2]/p/i[1]/text()')[0]
        score_2 = info.xpath('div/div/div[2]/p/i[2]/text()')[0]
        score = score_1 + score_2
        get_info(info_url,name,star,release_time,score)

获取二级信息

在二级网页中,我们需要获取的数据信息是电影类型和时长。
首先,我们先看网页源代码,如下所示:
Python爬取猫眼电影TOP100的电影数据(爬取代码+数据可视化分析)_第3张图片
Python爬取猫眼电影TOP100的电影数据(爬取代码+数据可视化分析)_第4张图片
由这两张图片我们可以看到,猫眼电影TOP100二级信息中的电影数据信息在网页源代码中的标签也是相同的,故在爬取时同样使用一个for循环对全部电影的二级数据信息进行爬取。
博主在爬取二级数据时,同样采用的是xpath方法获取电影数据数据信息,上代码:

def get_info(url,name,star,time,score):
    res = requests.get(url, headers=headers)
    html = etree.HTML(res.text)
    style = html.xpath('/html/body/div[3]/div/div[2]/div[1]/ul/li[1]/text()')[0]
    long_time = html.xpath('/html/body/div[3]/div/div[2]/div[1]/ul/li[2]/text()')[0].split('/')[1].strip()
    print(name,star,time,score,style,long_time)
   writer.writerow([name,star,time,score,style,long_time])

注意:在获取二级信息之后,需要将一级信息同二级信息一起写入CSV文件中。

数据存储

本文将数据信息存储到了CSV文件中。
将信息存储到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成功!')

本文中,博主并未使用该方式进行存储信息,博主的方法如下:

fp = open('maoyan_2.csv','w',encoding='utf-8',newline='')
writer = csv.writer(fp)
writer.writerow(['name','star','time','score','style','long_time'])

完整代码

import requests
from lxml import etree
import csv


headers = {
     
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
}

def get_url(url):
    res = requests.get(url,headers=headers)
    html = etree.HTML(res.text)
    infos = html.xpath('//dl[@class="board-wrapper"]/dd')
    for info in infos:
        name = info.xpath('div/div/div[1]/p[1]/a/text()')[0]
        info_url = 'http://maoyan.com' + info.xpath('div/div/div[1]/p[1]/a/@href')[0]
        star = info.xpath('div/div/div[1]/p[2]/text()')[0].strip()
        release_time = info.xpath('div/div/div[1]/p[3]/text()')[0].strip()
        score_1 = info.xpath('div/div/div[2]/p/i[1]/text()')[0]
        score_2 = info.xpath('div/div/div[2]/p/i[2]/text()')[0]
        score = score_1 + score_2
        # print(name,star,release_time,score,info_url)
        get_info(info_url,name,star,release_time,score)

def get_info(url,name,star,time,score):
    res = requests.get(url, headers=headers)
    html = etree.HTML(res.text)
    style = html.xpath('/html/body/div[3]/div/div[2]/div[1]/ul/li[1]/text()')[0]
    long_time = html.xpath('/html/body/div[3]/div/div[2]/div[1]/ul/li[2]/text()')[0].split('/')[1].strip()
    print(name,star,time,score,style,long_time)
    writer.writerow([name,star,time,score,style,long_time])

if __name__ == '__main__':
    fp = open('maoyan_2.csv','w',encoding='utf-8',newline='')
    writer = csv.writer(fp)
    writer.writerow(['name','star','time','score','style','long_time'])
    urls = ['http://maoyan.com/board/4?offset={}'.format(str(i)) for i in range(0, 100, 10)]
    for url in urls:
        get_url(url)

CSV截图:

因为要进行数据分析,所以博主将CSV文件进行了一些修改,修改后的CSV文件如下:

数据可视化分析

本文使用jupyter进行数据分析。

查看CSV文件的数据

首先,我们来看看采用jupyter读取的CSV文件中的数据:

import pandas as pd
import random
data=pd.read_csv(r'C:\Users\ASUS\Desktop\Python实训\maoyan_2.csv')
data

Python爬取猫眼电影TOP100的电影数据(爬取代码+数据可视化分析)_第5张图片
查看CSV文件的基本信息

import pandas as pd
import numpy as np
data=pd.read_csv(r'C:\Users\ASUS\Desktop\Python实训\maoyan_2.csv')
data.info()

Python爬取猫眼电影TOP100的电影数据(爬取代码+数据可视化分析)_第6张图片
由此可见,本次分析的CSV文件中有8列,100行数据信息,并且没有空值。

查看重复值

查看CSV文件中的数据信息是否有重复的值:

data.duplicated().value_counts()

在这里插入图片描述
由此可见,该CSV文件中并没有重复的值。

删除无意义的列(或行)

CSV文件里存储的演员和简介主要是电影的主演演员和电影的简介,这两列对本文的数据可视化分析是无意义的,故我们可以把这两列删除,然后对其他存储信息进行数据分析。
本文使用drop()方法对数据进行删除,删除之后剩下电影名,上映时间,评分,电影类型和时长这五列数据信息,删除代码如下:

data=data.drop(columns=["演员","简介"])
data

删除之后的数据信息如下:
Python爬取猫眼电影TOP100的电影数据(爬取代码+数据可视化分析)_第7张图片

上映年份和评分信息可视化

1、

data.plot.scatter(x='year',y='rate')

Python爬取猫眼电影TOP100的电影数据(爬取代码+数据可视化分析)_第8张图片
观察该散点图可知,在猫眼TOP100排行榜中的100部电影中,1990-2020年期间的电影发布数量较多,但评分比较散乱;1940-1980年其间在猫眼TOP100排行榜上的有5部电影,其中3部评分在9分以上,2部在9分以下。总的来看,大部分电影还是在9分左右。

2、
下面这两个图是评分和上映年份的趋势图:

import matplotlib.pylab as plt
data['评分'].plot()
plt.xlabel('count')
plt.ylabel('score')

import matplotlib.pylab as plt
data['上映年份'].plot()
plt.xlabel('count')
plt.ylabel('year')

Python爬取猫眼电影TOP100的电影数据(爬取代码+数据可视化分析)_第9张图片
Python爬取猫眼电影TOP100的电影数据(爬取代码+数据可视化分析)_第10张图片
3、
(1)统计所有电影出现的评分的情况,并且统计这些情况出现的次数。

data1=data.drop_duplicates(subset=['评分'])
d=pd.DataFrame(data1['评分'],columns=['评分'])
d['count']=[len(data[data['评分']==8]),len(data[data['评分']==8.1]),
             len(data[data['评分']==8.2]),len(data[data['评分']==8.3]),
             len(data[data['评分']==8.4]),len(data[data['评分']==8.5]),
             len(data[data['评分']==8.6]),len(data[data['评分']==8.7]),
             len(data[data['评分']==8.8]),len(data[data['评分']==8.9]),
             len(data[data['评分']==9]),len(data[data['评分']==9.1]),
             len(data[data['评分']==9.2]),len(data[data['评分']==9.3]),
             len(data[data['评分']==9.4]),len(data[data['评分']==9.5]),
             len(data[data['评分']==9.6]),len(data[data['评分']==9.7])]
    
d

Python爬取猫眼电影TOP100的电影数据(爬取代码+数据可视化分析)_第11张图片
(2)将这些评分情况生成饼状图和柱状图
①饼状图:

plt.figure(figsize=(6,6))
label=d['评分'].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,0.01,0.01]
plt.pie(x=d['count'].values.tolist(),explode=explode,labels=label,autopct='%1.1f%%')
plt.title('Score')
plt.show()

Python爬取猫眼电影TOP100的电影数据(爬取代码+数据可视化分析)_第12张图片
②柱状图:

plt.rcParams['figure.figsize']=[13,8]#这是这个表的大小
lable=d['评分'].values.tolist()#刻度标签

plt.bar(range(18),d['count'].values.tolist(),width=0.5)#18根柱子,对应值,宽度
#下面两个是x轴,y轴的表是的是啥
plt.ylabel('count',fontsize=15)
plt.xlabel("score",fontsize=15)
#每一个柱子代表的城市
plt.xticks(range(18),lable)
plt.title('100 movie Score')
plt.show()

Python爬取猫眼电影TOP100的电影数据(爬取代码+数据可视化分析)_第13张图片
由饼状图和柱状图可知,电影评分为9.2的电影居多,而评分为9.1、9.8、8.5的电影数量占有百分之三十,而其他评分的电影就比较少了。
4、
(1)统计所有电影出现的上映年份的情况,并且统计这些情况出现的次数。

df=data.drop_duplicates(subset=['上映年份'])
d1=pd.DataFrame(df['上映年份'],columns=['上映年份'])
d1['count']=[len(data[data['上映年份']==1939]),len(data[data['上映年份']==1953]),
             len(data[data['上映年份']==1957]),len(data[data['上映年份']==1975]),
             len(data[data['上映年份']==1987]),len(data[data['上映年份']==1988]),
             len(data[data['上映年份']==1989]),len(data[data['上映年份']==1990]),
             len(data[data['上映年份']==1992]),len(data[data['上映年份']==1993]),
             len(data[data['上映年份']==1994]),len(data[data['上映年份']==1995]),
             len(data[data['上映年份']==1997]),len(data[data['上映年份']==1998]),
             len(data[data['上映年份']==1999]),len(data[data['上映年份']==2000]),
             len(data[data['上映年份']==2001]),len(data[data['上映年份']==2003]),
            len(data[data['上映年份']==2004]),len(data[data['上映年份']==2005]),
            len(data[data['上映年份']==2006]),len(data[data['上映年份']==2008]),
            len(data[data['上映年份']==2009]),len(data[data['上映年份']==2010]),
            len(data[data['上映年份']==2011]),len(data[data['上映年份']==2012]),
            len(data[data['上映年份']==2013]),len(data[data['上映年份']==2014]),
            len(data[data['上映年份']==2015]),len(data[data['上映年份']==2016]),
            len(data[data['上映年份']==2017]),len(data[data['上映年份']==2018]),
            len(data[data['上映年份']==2019]),len(data[data['上映年份']==2020])]
    
d1

Python爬取猫眼电影TOP100的电影数据(爬取代码+数据可视化分析)_第14张图片
(2)将这些上映年份情况生成柱状图:

y=data['上映年份'].value_counts()
y.columns=['year','count']
plt.figure(figsize=(15,6.5))
y.sort_index().plot(kind='bar')

Python爬取猫眼电影TOP100的电影数据(爬取代码+数据可视化分析)_第15张图片

类型信息可视化

同一部电影的类型也可能会有多个类型,下面博主将本次CSV中的电影类型进行查看和总和。

all_type = df['类型'].str.split('、').apply(pd.Series)
all_type.head(67)

Python爬取猫眼电影TOP100的电影数据(爬取代码+数据可视化分析)_第16张图片
从这个图中我们可以看到:有些电影有一种类型,而有些电影有2-4种类型。该图片中有很多空值,我们可以将这些空值用“0”进行替换,然后再将这些类型进行计数和总和。
下面就是将空值替换,然后汇总的代码和数据显示:

all_type = df['类型'].str.split('、').apply(pd.Series)
all_type = all_type.apply(pd.value_counts).fillna('0')
all_type.columns = ['tpye1','type2','type3','type4']
all_type['tpye1'] = all_type['tpye1'].astype(int)
all_type['type2'] = all_type['type2'].astype(int)
all_type['type3'] = all_type['type3'].astype(int)
all_type['type4'] = all_type['type4'].astype(int)
all_type.head(67)

all_type['all_counts'] = all_type['tpye1']+all_type['type2']+all_type['type3']+all_type['type4']

all_type = all_type.sort_values(['all_counts'],ascending=False)
all_type.head(67)

Python爬取猫眼电影TOP100的电影数据(爬取代码+数据可视化分析)_第17张图片
我们将这些类型情况生成一个柱状图来观察一下:

type_rank = pd.DataFrame({
     'counts':all_type['all_counts']})
type_rank
type_rank.sort_values(by='counts',ascending=False).plot(kind='bar',figsize=(14,6))

Python爬取猫眼电影TOP100的电影数据(爬取代码+数据可视化分析)_第18张图片
由此图可见,猫眼TOP100排行榜中的,几乎8百分之八十的电影都包含剧情这一种类型;其次大家比较爱看的是冒险、喜剧、爱情、动作这些类型的电影;而西部、灾难、古装、歌舞这些类型电影在排行榜上就比较少,几乎没有。

国家信息可视化

同一部电影的可能由多个国家联合制作,下面博主将本次CSV中的电影制作国家进行查看和总和。

all_country = df['国家'].str.split('、').apply(pd.Series)
all_country.head(67)

Python爬取猫眼电影TOP100的电影数据(爬取代码+数据可视化分析)_第19张图片
从这个图中我们可以看到:有些电影有一个国家制作,而有些电影有2-4个国家制作。并且该图片中有很多空值,我们可以将这些空值用“0”进行替换,然后再将这些类型进行计数和总和。
下面就是将空值替换,然后汇总的代码和数据显示:

all_country = df['国家'].str.split('、').apply(pd.Series)
all_country = all_country.apply(pd.value_counts).fillna('0')
all_country.columns = ['area1','area2','area3','area4']
all_country['area1'] = all_country['area1'].astype(int)
all_country['area2'] = all_country['area2'].astype(int)
all_country['area3'] = all_country['area3'].astype(int)
all_country['area4'] = all_country['area4'].astype(int)
all_country['all_counts'] = all_country['area1']+all_country['area2']+all_country['area3']+all_country['area4']
all_country.sort_values(['all_counts'],ascending=False)
all_country

Python爬取猫眼电影TOP100的电影数据(爬取代码+数据可视化分析)_第20张图片
我们将这些制作国家情况生成一个柱状图来观察一下:
Python爬取猫眼电影TOP100的电影数据(爬取代码+数据可视化分析)_第21张图片
由此图可见,猫眼TOP100排行榜中的,几乎8百分之八十的电影都由美国制作,可见美国在电影制作方面还是很厉害的啊;其次是英国、中国、意大利、德国、法国这些国家;而西班牙、黎巴嫩、阿根廷、比利时这些国家制作电影在排行榜上就比较少,几乎没有。

以上就是博主本次的总结。由于数据量太小,所以做的分析并不是很全面。如果有什么不足之处,欢迎大家进行评论,我也会进行改正!
欢迎大家一起探讨啊!如果有喜欢的,希望能给我点个赞,谢谢大家了!

你可能感兴趣的:(python,python,csv,数据可视化)