电影Top25数据分析

先去打开目标网页进行抓包分析:

目标网址:

https://movie.douban.com/top250?0&filter=

电影Top25数据分析_ico

浏览器抓包分析

导入库:

import pandas as pd
import requests
from bs4 import BeautifulSoup
from matplotlib import pyplot as plt

完整代码如下:

import pandas as pd
import requests
from bs4 import BeautifulSoup
from matplotlib import pyplot as plt

'''
    目的是爬取'电影排名','电影名','上映时间','导演','主演','电影类型','电影评分','评价人数','电影链接'
'''

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                  'Chrome/92.0.4515.107 Safari/537.36 Edg/92.0.902.55'}  # 用header伪装成浏览器访问而不是Python访问,这样能让网站接入

url1 = []  # 所有电影的URL
url = 'https://movie.douban.com/top250?0&filter='  # 每一个电影相当于有一个网站,把每个网址存在url1这个列表里面
print('正在处理url:', url)
response = requests.get(url=url, headers=headers)  # 接入网址
soup = BeautifulSoup(response.text,
                     'html.parser')  # BeautifulSoup是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式
url_mv_list = soup.select('#content > div > div.article > ol > li > div > div.info > div.hd > a')  # 筛选元素的a标签,css语法
for index_url in range(len(url_mv_list)):
    url_mv = url_mv_list[index_url]['href']
    url1.append(url_mv)


def loading_mv(url, number):  # 函数,爬取所有的电影信息
    list_mv = [number + 1]  # 存储电影信息

    # 解析网页
    response_mv = requests.get(url=url, headers=headers)
    soup_mv = BeautifulSoup(response_mv.text, 'html.parser')

    # 爬取电影名
    mv_name = soup_mv.find_all('span', attrs={'property': 'v:itemreviewed'})  # 电影名
    mv_name = mv_name[0].get_text()  # 解析出名字,get_text
    list_mv.append(mv_name)  # 电影信息列表加入名字
    # print(mv_name)

    # 爬取电影的上映时间
    mv_year = soup_mv.select('span.year')  # 电影上映时间
    mv_year = mv_year[0].get_text()[1:5]  # 解析出上映时间
    list_mv.append(mv_year)  # 添加电影的年份
    # print(mv_year)

    # 爬取导演信息
    list_mv_director = []  # 导演
    mv_director = soup_mv.find_all('a', attrs={'rel': "v:directedBy"})
    for director in mv_director:
        list_mv_director.append(director.get_text())
    string_director = '/'.join(list_mv_director)  # 重新定义格式
    list_mv.append(string_director)
    # print(list_mv_director)

    # 爬取主演信息
    list_mv_star = []  # 主演
    mv_star = soup_mv.find_all('span', attrs={'class': 'actor'})
    mv_star = mv_star[0].get_text().strip().split('/')
    mv_first_star = mv_star[0].split(':')
    list_mv_star.append(mv_first_star[-1].strip())
    del mv_star[0]  # 去除'主演'字段
    for star in mv_star:
        list_mv_star.append(star.strip())
    string = '/'.join(list_mv_star)  # 重新定义格式
    list_mv.append(string)

    # 爬取电影类型
    list_mv_type = []  # 电影类型
    mv_type = soup_mv.find_all('span', attrs={'property': 'v:genre'})
    for type in mv_type:
        list_mv_type.append(type.get_text())
    string_type = '/'.join(list_mv_type)
    list_mv.append(string_type)
    # print(list_mv_type)

    # 爬取电影评分
    mv_score = soup_mv.select('strong.ll.rating_num')  # 评分
    mv_score = mv_score[0].get_text()
    list_mv.append(mv_score)

    # 爬取评价人数
    mv_evaluation_num = soup_mv.select('a.rating_people')  # 评价人数
    mv_evaluation_num = mv_evaluation_num[0].get_text().strip()
    list_mv.append(mv_evaluation_num)

    # 爬取剧情简介
    mv_plot = soup_mv.find_all('span', attrs={"class": "all hidden"})  # 剧情简介
    if mv_plot == []:
        list_mv.append(None)
    else:
        string_plot = mv_plot[0].get_text().strip().split()
        new_string_plot = ' '.join(string_plot)
        list_mv.append(new_string_plot)

    # 加入电影网址
    list_mv.append(url)

    return list_mv


list_all = []

dict_mv_info = {}
for number in range(len(url1)):
    mv_info = loading_mv(url1[number], number)
    list_all.append(mv_info)

df = pd.DataFrame(list_all, columns=['电影排名', '电影名', '上映时间', '导演', '主演', '电影类型', '电影评分', '评价人数', '电影简介', '电影链接'])

# 电影类型柱状图统计
df.to_excel(r'豆瓣电影Top25.xlsx')
y = df['电影类型']

dict_type = {}
for type in y:
    line = type.split('/')
    for t in line:
        dict_type[t] = dict_type.get(t, 0) + 1

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.xticks(rotation=30)
plt.subplot(2, 1, 1)
plt.bar(dict_type.keys(), dict_type.values(), color='g')
plt.xlabel('类型', fontdict={'family': 'SimSun', 'color': 'black', 'size': 10}, labelpad=20)
plt.ylabel('个数', fontdict={'family': 'SimSun', 'color': 'black', 'size': 10}, labelpad=20)
plt.title(label='排行前25电影类型直方图', fontdict={'family': 'KaiTi', 'color': 'red', 'size': 10}, loc='center')

# 电影主演折线图统计
z = df['导演']

dict_actor = {}
for dir in z:
    line = dir.split('/')
    for t in line:
        dict_actor[t] = dict_actor.get(t, 0) + 1

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

plt.subplot(2, 1, 2)
plt.plot(dict_actor.keys(), dict_actor.values(), color='g')
plt.title(label='排行前25电影主演折线图', fontdict={'family': 'KaiTi', 'color': 'red', 'size': 10}, loc='center')

plt.xticks(rotation=290)
plt.xlabel('导演', fontdict={'family': 'SimSun', 'color': 'black', 'size': 10}, labelpad=20)
plt.ylabel('个数', fontdict={'family': 'SimSun', 'color': 'black', 'size': 10}, labelpad=20)
plt.tight_layout()
plt.show()

运行效果

电影Top25数据分析_ico_02

电影Top25数据分析_数据分析_03


第一次运行可以出结果,如果后面运行不行就是ip被封了,换ip,用ip代理池也行,

或者把里面数据分析出图的代码单独拿出来运行也行,因为ip第一次请求会请求爬取到数据,后面次数多了就不行了。