豆瓣电影top250信息爬取与数据分析

爬取豆瓣电影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年前的电影数量加起来还要多。

猜你喜欢

转载自blog.csdn.net/Kyrie_tim/article/details/93196253