爬取豆瓣电影top250的电影信息
网页链接: https://movie.douban.com/top250
技术路线:requests - bs4 - re
输出:保存为csv格式文件
import re
import requests
from bs4 import BeautifulSoup
def getHTMLText(url, code="utf-8"):
try:
r = requests.get(url)
r.raise_for_status()
r.encoding = code
return r.text
except:
return "爬取出错!"
def parseText(text, movieInfo):
soup = BeautifulSoup(text, 'html.parser')
olTag = soup.find('ol', class_='grid_view')
details = olTag.find_all('li')
for detail in details:
movieRank = detail.find('em').text #电影排名
movieName = '《' + detail.find('span', class_='title').text + '》' #电影名称
movieScore = detail.find('span', class_='rating_num').text + '分' #电影评分
movieCommentNum = detail.find(text=re.compile('\d+人评价')).string #评价人数
movieReview = '"' + detail.find('span', class_='inq').text + '"' #电影短评
movieP = detail.find('p').text
movieP1 = movieP.split('\n')[1]
movieP2 = movieP.split('\n')[2]
movieDirector = movieP1.split('\xa0')[0].strip()[4:] #导演
movieYear = re.findall(r'\d{4}', movieP2)[0] #上映年份
movieCountry = movieP2.split('\xa0/\xa0')[-2] #制片国家
movieType = movieP2.split('\xa0/\xa0')[-1].strip() #电影类型
# 将爬取的信息存入列表
movieInfo.append([movieRank, movieName, movieDirector, movieYear, movieCountry, movieType, movieScore, movieCommentNum, movieReview])
def writeFile(fpath, movieInfo):
with open(fpath, 'w', encoding='utf-8') as f:
for info in movieInfo:
f.write(','.join(info) + '\n')
if __name__ == '__main__':
movieInfo = [['电影排名', '电影名称', '导演', '上映年份', '制片国家', '电影类型', '电影评分', '评价人数', '电影短评']]
for i in range(0, 250, 25):
url = 'https://movie.douban.com/top250?start=' + str(i)
text = getHTMLText(url)
parseText(text, movieInfo)
writeFile('movie_top250.csv', movieInfo)
print('爬取完成!')
对爬取到的数据进行分析
先导入模块并读取csv文件,预览数据。
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rcParams['font.family'] = 'SimHei'
mpl.rcParams['axes.unicode_minus'] = False
mpl.rcParams['font.size'] = 15
df = pd.read_csv('movie_top250.csv')
display(df)
查看缺失值和重复值,都为0,爬取的数据情况较好。
电影评分的统计情况
df['电影评分'] = df['电影评分'].str.rstrip('分')
df['电影评分'] = df['电影评分'].astype(np.float64)
score = df['电影评分'].value_counts().sort_index()
plt.figure(figsize = (8,5))
score.plot(kind = 'bar', color = 'orange', width = 0.7)
plt.xlabel('movie_score')
plt.ylabel('count')
plt.title('电影评分数量柱状图')
电影评分主要集中 8.5 到 9.2 之间,平均分值约为 8.84 ,最小值为 8.3 ,最大值为 9.6 。
扫描二维码关注公众号,回复:
6612004 查看本文章
电影评分和电影排名的关系
plt.figure(figsize=(10,8))
plt.scatter(df['电影评分'],df['电影排名'])
plt.xlabel('movie_score')
plt.ylabel('movie_rank')
plt.gca().invert_yaxis()
plt.title('电影评分与电影排名散点图')
随着电影评分的升高,电影排名也在提前,Pearson相关系数约为-0.73,为强相关性。
制片国家的上榜数排名情况
df_country = df['制片国家'].str.split(' ',expand = True)
ct1 = df_country.apply(pd.value_counts).fillna('0')
ct1 = ct1.astype(np.int64)
ct1['count'] = ct1.sum(axis = 1)
ct1.sort_values('count', ascending = False, inplace = True)
ct1['count'].plot.bar(figsize = (12,5), color = 'royalblue', legend = True, width = 0.6)
上榜数最多的国家是美国,香港排名第四,中国大陆排名第五。
关于电影类型的字段分析
df_type = df['电影类型'].str.split(' ',expand = True)
tp1 = df_type.apply(pd.value_counts).fillna('0')
tp1 = tp1.astype(np.int64)
tp1['count'] = tp1.sum(axis = 1)
tp1.sort_values('count', ascending = False, inplace = True)
tp1['count'].plot.bar(figsize = (12,5), color = 'green', legend = True)
可以看到,榜单中剧情类的电影数量遥遥领先,说明豆瓣用户比较愿意为剧情类型电影打高分。
导演上榜次数排名情况
df_director = df['导演'].str.split(' / ',expand = True)
drt1 = df_director.apply(pd.value_counts).fillna('0')
drt1 = drt1.astype(np.int64)
drt1['count'] = drt1.sum(axis = 1)
drt1.sort_values('count', ascending = False, inplace = True)
drt1.drop([0,1], axis = 1, inplace = True)
drt1.index.name = '导演'
display(drt1[:10])
导演上榜次数名列前茅的有诺兰、宫崎骏、斯皮尔伯格,中国著名导演王家卫、李安、姜文也位列前十。
上映年份的分布情况
查看上映年份的最大值和最小值,分别为 1931年 和 2018年 。
plt.figure(figsize = (8,5))
plt.hist(df['上映年份'], bins = 30)
plt.xticks(range(1930,2021,10))
plt.xlabel('上映年份')
plt.ylabel('电影数量')
plt.title('电影上映年份直方图')
上映年份大多是集中在 1990年 - 2018年 之间。
year = pd.cut(df['上映年份'],bins = range(1930, 2021, 10), right = False)
yr1 = year.value_counts().sort_index()
yr1.plot.barh(color = 'green', alpha = 0.7)
for a,b in zip(yr1.values, range(len(yr1))):
plt.text(a+0.3, b, a, va='center')
榜单上的电影大部分在 1990年 到 2019年 之间上映,而且近20年的电影数量比20年前的电影数量加起来还要多。