猫眼电影爬虫和数据分析

    技术2022-07-16  79

    由于疫情关系,宅在家里。记录一下作业,猫眼电影爬虫及分析,爬取猫眼电影数据,并对爬取的数据进行分析和展示。

    猫眼电影爬虫

    基于requests库和lxml库进去猫眼电影TOP100榜电影爬取,爬取地址为:https://maoyan.com/board/4

    爬取的信息有:电影名字,主演名字,上映时间以及地点,猫眼评分得分,电影类型,电影时长。

    电影数据保存为.csv格式。表头:电影名字(title),主演名字(author),上映时间以及地点(pub_time),猫眼评分得分(star),电影类型(style),电影时长(long_time)。

    import requests from lxml import etree import csv headers = { # 设置header 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36' } def get_url(url): # top100电影获取 res = requests.get(url, headers=headers) # 请求 # print(res.text) html = etree.HTML(res.text) # 获取网页源码 infos = html.xpath('//dl[@class="board-wrapper"]/dd') # 获取页面的10部电影,xpath for info in infos: title = info.xpath('div/div/div[1]/p[1]/a/text()')[0] # 电影名称 author = info.xpath('div/div/div[1]/p[2]/text()')[0].strip().strip('主演:') # 电影主演,strip()去掉空格 pub_time = info.xpath('div/div/div[1]/p[3]/text()')[0].strip('上映时间:') # 上映时间 star_1 = info.xpath('div/div/div[2]/p/i[1]/text()')[0] # 得分1(整数部分) star_2 = info.xpath('div/div/div[2]/p/i[2]/text()')[0] # 得分2(小数部分) star = star_1 + star_2 # 电影得分 movie_url = 'https://maoyan.com' + info.xpath('div/div/div[1]/p[1]/a/@href')[0] # 电影的详细页 # print(title,author,pub_time,star,movie_url) get_info(movie_url, title, author, pub_time, star) # 进入电影的详细页爬取 print(‘保存完毕!’) def get_info(url, title, author, pub_time, star): # 电影详细获取 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().strip( '分钟') # 电影时长 print(title, author, pub_time, star, style, long_time) writer.writerow([title, author, pub_time, star, style, long_time]) # 写入数据 if __name__ == '__main__': fp = open('F://maoyan.csv', 'w', newline='', encoding='utf-8') # 存储文件 writer = csv.writer(fp) writer.writerow(['title', 'author', 'pub_time', 'star', 'style', 'long_time']) # 写入表头 urls = ['https://maoyan.com/board/4?offset={}'.format(str(i)) for i in range(0, 100, 10)] # url构造 for url in urls: get_url(url)

    数据分析

    数据分析和展示时基于pandas和matplotlib。

    分析了100部电影基本分析、演员出演这100部电影次数、电影的年份分布情况、电影的月份分布情况、电影的国家分布情况、前20部电影评分得分情况、电影的类型分布情况、电影的时长分布情况等。

    演员出演这100部电影次数 (1)读取电影数据。 (2)取出主演(author)一列数据,循环对其进行字符串拼接。 (3)以“,”为分隔符进行切割,统计演员的个数以及名字、演员名字出现的次数(实现方法很多,这里使用的是Counter模块)。 (4)选取出演次数最多的六位演员。构造水平轴数据author,垂直轴数据count。 (5)使用matplotlib的pyplot绘制条形图,设置title,xlabel,ylabel。 import pandas as pd from matplotlib import pyplot as plt from collections import Counter plt.rcParams['font.sans-serif'] = ['SimHei'] datas = pd.read_csv('maoyan.csv', encoding='utf-8') s = '' for i in range(99): s += datas.iloc[i, 1]+',' s += datas.iloc[99, 1] # 防止最后的空格 # print(s) authors = s.split(',') # print(authors) c = Counter(authors) # print(c) items = c.most_common(6) print(items) author = [] count = [] for item in items: author.append(item[0]) count.append(item[1]) # print(author) # print(count) plt.bar(author, count, color='orange') plt.title('出演次数最多的六位演员情况') plt.xlabel('演员') plt.ylabel('出演次数') plt.show()

    运行结果:

    电影的年份分布情况 (1)读取电影数据。 (2)取出上映时间及地点(pub_time)一列数据。 (3)以“-”为分隔符进行切割,取出第一个元素,第二个元素是月份。存储为新的一列year。 (4)使用groupby对year这一列按照年份进行分组,并统计次数。 (5)数据的index转化为列表作为水平轴数据,数据转化为list作为垂直轴数据。 (6)使用matplotlib的pyplot绘制折线图,设置title,xlabel,ylabel。 import pandas as pd from matplotlib import pyplot as plt plt.rcParams['font.sans-serif'] = ['SimHei'] datas = pd.read_csv('maoyan.csv', encoding='utf-8') datas['year'] = datas['pub_time'].str.split('-').str[0] datas['month'] = datas['pub_time'].str.split('-').str[1] year = datas.groupby('year')['year'].count() month = datas.groupby('month')['month'].count() # print(list(year.index)) # print(list(year)) # print(month) plt.figure(figsize=(20, 8), dpi=80) plt.plot(list(year.index), list(year)) plt.title('电影年份的分布情况') plt.xlabel('年份') plt.ylabel('电影数量') plt.grid(alpha=0.4) plt.show()

    运行结果:

    电影的国家分布情况 (1)读取电影数据。 (2)定义一个方法get_country(),对字符串进行切割,取出国家部分,中国香港返回中国,法国戛纳返回法国。 (3)取出上映时间及地点(pub_time)一列数据。 (4)分别进行get_country操作。存储为新的一列country。 (5)使用groupby对country这一列按照国家进行分组,并统计次数。 (6)数据的index转化为列表作为水平轴数据,数据转化为list作为垂直轴数据。 (7)使用matplotlib的pyplot绘制饼图,设置title,xlabel,ylabel。 import pandas as pd from matplotlib import pyplot as plt plt.rcParams['font.sans-serif'] = ['SimHei'] datas = pd.read_csv('maoyan.csv', encoding='utf-8') def get_country(s): country = s.split('(') if len(country) == 1: return '中国' else: temp = country[1].strip(')') if temp == '中国香港': return '中国' elif temp == '法国戛纳': return '法国' else: return temp datas['country'] = datas['pub_time'].map(get_country) # print(datas['country']) country = datas.groupby('country')['country'].count() # print(country) # print(list(country)) # print(list(country.index)) explods = [0, 0.2, 0, 0, 0, 0, 0, 0, 0] plt.pie(list(country), labels=list(country.index), autopct='%1.1f%%', explode=explods) plt.title('电影的国家分布情况') plt.show()

    运行结果:

    电影的时长分布情况 (1)读取电影数据。 (2)取出电影时长(long_time)一列数据。 (3)按照10分钟为一个长度归类 (4)使用matplotlib的pyplot绘制柱状图,设置title,xlabel,ylabel。 import pandas as pd from matplotlib import pyplot as plt plt.rcParams['font.sans-serif'] = ['SimHei'] datas = pd.read_csv('maoyan.csv', encoding='utf-8') long_time = list(datas['long_time']) # print(long_time) d = 10 num_bins = int((max(long_time) - min(long_time)) / d) plt.hist(long_time, range(min(long_time), max(long_time) + d, d), density=True) plt.xticks(range(min(long_time), max(long_time) + d, d)) plt.grid(alpha=0.4) plt.title('电影的时长分布情况') plt.xlabel('电影时长') plt.ylabel('比例') plt.show()

    运行结果: 【更多分析】 https://github.com/Tcrushes/crawler-analysis 【参考文献】 [1] matplotlib用户指南2020.04.08 [2] panluoluo. 猫眼电影爬虫及分析GitHub 2019.03.04

    Processed: 0.016, SQL: 9