【Python爬虫五十个小案例】爬取猫眼电影Top100

news2024/11/26 11:38:46

请添加图片描述

博客主页:小馒头学python

本文专栏: Python爬虫五十个小案例

专栏简介:分享五十个Python爬虫小案例

在这里插入图片描述

🐍引言

猫眼电影是国内知名的电影票务与资讯平台,其中Top100榜单是影迷和电影产业观察者关注的重点。通过爬取猫眼电影Top100的数据,我们可以分析当前最受欢迎的电影,了解电影市场的变化趋势。在本文中,我们将介绍如何使用Python实现爬取猫眼电影Top100榜单的过程,并通过简单的数据分析展示电影的评分分布及其它相关信息。

🐍准备工作

在开始爬虫之前,我们需要做一些准备工作:

🐍安装必要的库

首先,我们需要安装几个常用的Python库:

pip install requests beautifulsoup4 pandas matplotlib seaborn

🐍了解页面结构

使用浏览器的开发者工具打开猫眼电影Top100的网页,观察页面的DOM结构,找到包含电影信息的元素

下面是页面的大概结构

在这里插入图片描述

🐍分析猫眼电影Top100页面结构

猫眼电影Top100的URL通常是类似于 https://maoyan.com/board/4。我们可以通过浏览器开发者工具(F12)来查看HTML结构,识别出电影的名称、评分、上映时间等数据。通过<li class="board-item">标签,每个电影的信息都包含在这个标签下。我们需要提取出其中的子标签来获取所需的数据。

🐍 编写爬虫代码

接下来,我们编写爬虫代码,来抓取页面中的电影信息。爬虫的主要任务是获取电影的名称、评分、上映时间等数据,并处理分页逻辑,直到抓取完Top100。

import requests
from bs4 import BeautifulSoup
import pandas as pd

# 设置目标URL
url = 'https://maoyan.com/board/4'

# 发送请求
response = requests.get(url)
response.encoding = 'utf-8'

# 使用BeautifulSoup解析HTML
soup = BeautifulSoup(response.text, 'html.parser')

# 存储电影信息的列表
movies = []

# 提取电影列表
for item in soup.find_all('dd'):
    movie = {}
    movie['name'] = item.find('a').text.strip()  # 电影名称
    movie['score'] = item.find('p', class_='score').text.strip()  # 电影评分
    movie['release_time'] = item.find('p', class_='releasetime').text.strip()  # 上映时间
    
    movies.append(movie)

# 将数据保存到DataFrame
df = pd.DataFrame(movies)

# 输出前5行数据
print(df.head())

# 保存到CSV文件
df.to_csv('maoyan_top100.csv', index=False)

🐍数据清洗与存储

在爬取数据之后,我们需要进行数据清洗,确保抓取的数据是准确和完整的。例如:

  • 清理电影名称中的空格和特殊字符
  • 处理评分字段中缺失或非数字的情况
  • 上映时间可能需要转换为标准日期格式

使用pandas可以方便地进行数据清洗:

# 清洗数据:去除空值
df.dropna(inplace=True)

# 转换上映时间为标准格式
df['release_time'] = pd.to_datetime(df['release_time'], errors='coerce')

# 处理评分数据,将评分转换为浮动类型
df['score'] = pd.to_numeric(df['score'], errors='coerce')

🐍数据分析与可视化

通过简单的数据分析,我们可以查看电影评分的分布、上映年份的趋势等:

import matplotlib.pyplot as plt
import seaborn as sns

# 绘制评分分布图
plt.figure(figsize=(8, 6))
sns.histplot(df['score'], bins=20, kde=True)
plt.title('电影评分分布')
plt.xlabel('评分')
plt.ylabel('数量')
plt.show()

# 电影上映年份分布
df['release_year'] = df['release_time'].dt.year
plt.figure(figsize=(10, 6))
sns.countplot(x='release_year', data=df)
plt.title('电影上映年份分布')
plt.xticks(rotation=45)
plt.show()

🐍反爬虫机制与应对策略

猫眼电影网站有一定的反爬虫机制,比如限制频繁的请求。因此,在编写爬虫时,我们需要注意以下几个问题:

  • 使用User-Agent:模拟浏览器请求头,避免被识别为爬虫
  • 设置请求间隔:通过time.sleep()设置请求的间隔,防止过于频繁的请求
  • 使用代理:避免IP封禁
import time
import random

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

# 模拟延时,避免频繁请求
time.sleep(random.uniform(1, 3))

🐍完整源码

import requests
from bs4 import BeautifulSoup
import pandas as pd
import time
import random
import matplotlib.pyplot as plt
from matplotlib import rcParams
import seaborn as sns
import re

# 设置Matplotlib使用的字体为SimHei(黑体),以支持中文显示
rcParams['font.sans-serif'] = ['SimHei']  # 使用黑体
rcParams['axes.unicode_minus'] = False  # 解决负号 '-' 显示为方块的问题

# 设置目标URL
url = 'https://maoyan.com/board/4'

# 请求头,模拟浏览器访问
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}

# 发送请求
response = requests.get(url, headers=headers)
response.encoding = 'utf-8'

# 使用BeautifulSoup解析HTML
soup = BeautifulSoup(response.text, 'html.parser')

# 存储电影信息的列表
movies = []

# 提取电影列表
for item in soup.find_all('dd'):
    movie = {}

    # 获取电影名称,从a标签的title属性中提取
    movie['name'] = item.find('a')['title'].strip() if item.find('a') else 'N/A'

    # 获取评分,确保评分字段存在
    score_tag = item.find('p', class_='score')
    movie['score'] = score_tag.text.strip() if score_tag else 'N/A'

    # 获取上映时间,确保上映时间字段存在
    release_time_tag = item.find('p', class_='releasetime')
    release_time = release_time_tag.text.strip() if release_time_tag else 'N/A'

    # 使用正则表达式清洗数据,提取年份部分
    movie['release_time'] = re.findall(r'\d{4}', release_time)  # 匹配年份

    if movie['release_time']:
        movie['release_time'] = movie['release_time'][0]  # 只取第一个年份
    else:
        movie['release_time'] = 'N/A'  # 如果没有找到年份,设置为'N/A'

    # 将电影信息添加到列表中
    movies.append(movie)

# 将数据存储到pandas DataFrame
df = pd.DataFrame(movies)

# 输出前5行数据
print("爬取的数据:")
print(df.head())

# 数据清洗:去除空值并处理评分数据
df.dropna(subset=['score', 'release_time'], inplace=True)  # 删除评分和上映时间为空的行

# 将评分转换为数值类型,无法转换的设置为NaN
df['score'] = pd.to_numeric(df['score'], errors='coerce')

# 删除评分为空的行
df.dropna(subset=['score'], inplace=True)

# 将release_time列转换为数值类型的年份
df['release_year'] = pd.to_numeric(df['release_time'], errors='coerce')

# 输出清洗后的数据
print("清洗后的数据:")
print(df.head())

# 保存数据为CSV文件
df.to_csv('maoyan_top100.csv', index=False)

# 数据分析:电影评分分布
plt.figure(figsize=(8, 6))
sns.histplot(df['score'], bins=20, kde=True)
plt.title('电影评分分布')
plt.xlabel('评分')
plt.ylabel('数量')
plt.show()

# 数据分析:电影上映年份分布
plt.figure(figsize=(10, 6))
sns.countplot(x='release_year', data=df)
plt.title('电影上映年份分布')
plt.xticks(rotation=45)
plt.xlabel('年份')
plt.ylabel('电影数量')
plt.show()

# 结束
print("爬取和分析完成!数据已保存至 maoyan_top100.csv")

🐍翻页功能

我们完成了基本的功能,接下来我们为了爬取前100个电影(即10页数据),你需要构造爬虫来遍历每一页并合并数据。每一页的URL格式为https://www.maoyan.com/board/4?offset=n,其中n是每页的偏移量,分别为0、10、20、30等,

import requests
from bs4 import BeautifulSoup
import pandas as pd
import time
import random
import matplotlib.pyplot as plt
from matplotlib import rcParams
import seaborn as sns
import re

# 设置Matplotlib使用的字体为SimHei(黑体),以支持中文显示
rcParams['font.sans-serif'] = ['SimHei']  # 使用黑体
rcParams['axes.unicode_minus'] = False  # 解决负号 '-' 显示为方块的问题

# 设置目标URL基础部分
base_url = 'https://www.maoyan.com/board/4?offset={}'

# 请求头,模拟浏览器访问
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}

# 存储所有电影信息的列表
movies = []

# 爬取10页数据,每页偏移量为0, 10, 20, ..., 90
for offset in range(0, 100, 10):
    url = base_url.format(offset)  # 构造每一页的URL
    response = requests.get(url, headers=headers)
    response.encoding = 'utf-8'
    
    # 使用BeautifulSoup解析HTML
    soup = BeautifulSoup(response.text, 'html.parser')
    
    # 提取电影列表
    for item in soup.find_all('dd'):
        movie = {}
        
        # 获取电影名称,从a标签的title属性中提取
        movie['name'] = item.find('a')['title'].strip() if item.find('a') else 'N/A'
        
        # 获取评分,确保评分字段存在
        score_tag = item.find('p', class_='score')
        movie['score'] = score_tag.text.strip() if score_tag else 'N/A'
        
        # 获取上映时间,确保上映时间字段存在
        release_time_tag = item.find('p', class_='releasetime')
        release_time = release_time_tag.text.strip() if release_time_tag else 'N/A'
        
        # 使用正则表达式清洗数据,提取年份部分
        movie['release_time'] = re.findall(r'\d{4}', release_time)  # 匹配年份

        if movie['release_time']:
            movie['release_time'] = movie['release_time'][0]  # 只取第一个年份
        else:
            movie['release_time'] = 'N/A'  # 如果没有找到年份,设置为'N/A'
        
        # 将电影信息添加到列表中
        movies.append(movie)
    
    # 随机延迟,避免频繁请求被封禁
    time.sleep(random.uniform(1, 3))

# 将数据存储到pandas DataFrame
df = pd.DataFrame(movies)

# 输出前5行数据
print("爬取的数据:")
print(df.head())

# 数据清洗:去除空值并处理评分数据
df.dropna(subset=['score', 'release_time'], inplace=True)  # 删除评分和上映时间为空的行

# 将评分转换为数值类型,无法转换的设置为NaN
df['score'] = pd.to_numeric(df['score'], errors='coerce')

# 删除评分为空的行
df.dropna(subset=['score'], inplace=True)

# 将release_time列转换为数值类型的年份
df['release_year'] = pd.to_numeric(df['release_time'], errors='coerce')

# 输出清洗后的数据
print("清洗后的数据:")
print(df.head())

# 保存数据为CSV文件
df.to_csv('maoyan_top100.csv',encoding='utf-8-sig' ,index=False)

# 数据分析:电影评分分布
plt.figure(figsize=(8, 6))
sns.histplot(df['score'], bins=20, kde=True)
plt.title('电影评分分布')
plt.xlabel('评分')
plt.ylabel('数量')
plt.show()

# 数据分析:电影上映年份分布
plt.figure(figsize=(10, 6))
sns.countplot(x='release_year', data=df)
plt.title('电影上映年份分布')
plt.xticks(rotation=45)
plt.xlabel('年份')
plt.ylabel('电影数量')
plt.show()

# 结束
print("爬取和分析完成!数据已保存至 maoyan_top100.csv")

遍历10页

  • 我们使用range(0, 100, 10)来设置偏移量,依次爬取从offset=0offset=90的URL
  • 每一页的URL由base_url.format(offset)生成。

随机延迟

  • 为了避免频繁请求导致被封禁,爬虫请求每一页后,加入了time.sleep(random.uniform(1, 3)),模拟随机延迟

爬取并合并数据

  • 所有电影信息都会存储到movies列表中,最后通过pandasDataFrame进行数据整合

运行结果
在这里插入图片描述
在这里插入图片描述

下图展示了电影评分分布情况还有电影上映年份的分布
在这里插入图片描述
在这里插入图片描述

🐍结语

通过本篇博客,我们展示了如何使用Python爬虫技术抓取猫眼电影Top100的数据,并进行简单的数据清洗与分析。除了数据抓取和分析,我们还学习了如何应对反爬虫机制。通过这些知识,我们可以很好的进行后续的数据分析,或者可以查看自己喜欢哪个电影,当然本节主要还是为了练手,为了后续我们进行其他项目任务

若感兴趣可以访问并订阅我的专栏:Python爬虫五十个小案例:https://blog.csdn.net/null18/category_12840403.html?fromshare=blogcolumn&sharetype=blogcolumn&sharerId=12840403&sharerefer=PC&sharesource=null18&sharefrom=from_link

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2247816.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Oh-My-ZSH安装教程

1. 安装zsh sudo apt-get install zsh2.安装on-my-zsh wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | sh上面方式很大可能因为网络连接问题而失败&#xff0c;可以通过以下方式&#xff1a; git clone gitgithub.com:ohmyzsh/ohmyzsh…

三六零[601360]行情数据接口

1、三六零&#xff1a;实时行情 Restful API # 测试接口&#xff1a;可以复制到浏览器打开 https://tsanghi.com/api/fin/stock/XSHG/realtime?tokendemo&ticker601360获取股票实时行情&#xff08;开、高、低、收、量&#xff09;。 请求方式&#xff1a;GET。 Python示例…

用 OceanBase 4.3.3,搭建《黑神话:悟空》的专属游戏AI助手

本文分享了如何基于 OceanBase 4.3.3 bp1 社区版的向量检索能力&#xff0c;通过几条简单的命令&#xff0c;快速搭建一个定制化的专属游戏助手的过程。 背景 在 OceanBase 最新推出 V 4.3.3 免费试用的同时&#xff0c;也同时发布了几个基于OB Cloud 的向量能力&#xff0c;搭…

tableau练习-制作30个图表

一、导入数据 1、导入数据 -添加-添加连接-到文件-excel格式用第一个excel导入&#xff0c;csv格式用第二个文本格式导入 2、连接数据 -从旁边这里直接拖到中间 标头连接 -日期若不一致需调节日期格式 3、保存数据 点击数据提取-再保存数据&#xff0c;保存为twbx格式 二、设计…

QT QHorizontalSpacer控件 全面详解

本系列文章全面的介绍了QT中的57种控件的使用方法以及示例,包括 Button(PushButton、toolButton、radioButton、checkBox、commandLinkButton、buttonBox)、Layouts(verticalLayout、horizontalLayout、gridLayout、formLayout)、Spacers(verticalSpacer、horizontalSpacer)、…

第六届智能控制、测量与信号处理国际学术会议 (ICMSP 2024)

重要信息 2024年11月29日-12月1日 中国陕西西安石油大学雁塔校区 大会官网&#xff1a;www.icmsp.net 大会简介 第六届智能控制、测量与信号处理国际学术会议&#xff08;ICMSP 2024&#xff09;由西安石油大学、中海油田服务股份有限公司、浙江水利水电学院与中国石油装备…

Qt中2D绘制系统

目录 一、Qt绘制系统 1.1Qt绘制基本概念 1.2 绘制代码举例 1.3画家 1.3.1 QPainter的工作原理&#xff1a; 1.3.2 自定义绘制饼状图&#xff1a; 1.4画笔和画刷 1.4.1画笔 1.4.2 画刷填充样式 1.5 反走样和渐变 1.6绘制设备 1.7坐标变换 1.8QPainterPath 1.9绘制文…

Linux——Uboot命令使用

什么是Uboot&#xff1f; 1&#xff09;Uboot是一个裸机程序&#xff0c;比较复杂。类似我们PC机的BIOS程序。 2&#xff09;Uboot就是一个bootloader&#xff0c;作用就是用于启动Linux或者其他系统&#xff0c;Uboot最主要的工作是初始化DDR&#xff0c;因为Linux的运行是运行…

2024智能机器人与自动控制国际学术会议 (IRAC 2024)

主办&#xff0c;承办&#xff0c;支持单位 会议官网 www.icirac.org 大会时间&#xff1a;2024年11月29-12月1日 大会简介 2024智能机器人与自动控制国际学术会议 &#xff08;IRAC 2024&#xff09;由华南理工大学主办&#xff0c;会议将于2024年11月29日-12月1日在中国广…

Linux网络——NAT/代理服务器

一.NAT技术 1.NAT IP转换 之前我们讨论了, IPv4 协议中, IP 地址数量不充足的问题&#xff0c;NAT 技术就是当前解决 IP 地址不够用的主要手段, 是路由器的一个重要功能。 NAT 能够将私有 IP 对外通信时转为全局 IP. 也就是一种将私有 IP 和全局IP 相互转化的技术方法: 很…

【架构】主流企业架构Zachman、ToGAF、FEA、DoDAF介绍

文章目录 前言一、Zachman架构二、ToGAF架构三、FEA架构四、DoDAF 前言 企业架构&#xff08;Enterprise Architecture&#xff0c;EA&#xff09;是指企业在信息技术和业务流程方面的整体设计和规划。 最近接触到“企业架构”这个概念&#xff0c;转念一想必定和我们软件架构…

亚信安全发布《2024年第三季度网络安全威胁报告》

《亚信安全2024年第三季度网络安全威胁报告》的发布旨在从一个全面的视角解析当前的网络安全威胁环境。此报告通过详尽梳理和总结2024年第三季度的网络攻击威胁&#xff0c;目的是提供一个准确和直观的终端威胁感知。帮助用户更好地识别网络安全风险&#xff0c;并采取有效的防…

【c++】模板详解(2)

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;C 目录 前言 一、非类型模板参数 二、模板的特化 1. 概念 2. 场景举例 3. 函数模板的特化 4. 类模板的特化 全特化 偏特化 1. 部分特化 2. 对参数的…

红队笔记--W1R3S、JARBAS、SickOS、Prime打靶练习记录

W1R3S(思路为主) 信息收集 首先使用nmap探测主机&#xff0c;得到192.168.190.147 接下来扫描端口&#xff0c;可以看到ports文件保存了三种格式 其中.nmap和屏幕输出的一样&#xff1b;xml这种的适合机器 nmap -sT --min-rate 10000 -p- 192.168.190.147 -oA nmapscan/ports…

Qt/C++基于重力模拟的像素点水平堆叠效果

本文将深入解析一个基于 Qt/C 的像素点模拟程序。程序通过 重力作用&#xff0c;将随机分布的像素点下落并水平堆叠&#xff0c;同时支持窗口动态拉伸后重新计算像素点分布。 程序功能概述 随机生成像素点&#xff1a;程序在初始化时随机生成一定数量的像素点&#xff0c;每个…

十一月二十五

双向循环链表 class Node:#显性定义出构造函数def __init__(self,data):self.data data #普通节点的数据域self.next None #保存下一个节点的链接域self.prior None #保存前一个节点饿链接域 class DoubleLinkLoop:def __init__(self, node Node):self.head nodeself.siz…

Python + 深度学习从 0 到 1(00 / 99)

希望对你有帮助呀&#xff01;&#xff01;&#x1f49c;&#x1f49c; 如有更好理解的思路&#xff0c;欢迎大家留言补充 ~ 一起加油叭 &#x1f4a6; 欢迎关注、订阅专栏 【深度学习从 0 到 1】谢谢你的支持&#xff01; ⭐ 什么是深度学习&#xff1f; 人工智能、机器学习与…

UG NX二次开发(C++)-UIStyler-指定平面的对象和参数获取

文章目录 1、前言2、在UG NX中创建平面和一个长方体,3、在UI Styler中创建一个UI界面4、在VS中创建一个工程4.1 创建并添加工程文件4.2 在Update_cb方法中添加选择平面的代码4.3 编译完成并测试效果1、前言 在采用NXOpen C++进行二次开发时,采用Menu/UIStyler是一种很常见的…

C# 命令行运行包

环境&#xff1a;net6 nuget包&#xff1a;Cliwrap 3.6.7 program&#xff1a; 相当于cmd运行命令&#xff1a;nuget search json static async Task Main(string[] args) {var cmd Cli.Wrap("D:\\软件\\Nuget\\nuget.exe").WithArguments(args >args.Add("…

长三角文博会:Adobe国际认证体系推动设计人才评价新标准

2024年11月22日&#xff0c;由上海、江苏、浙江、安徽三省一市党委宣传部共同发起的第五届长三角文化博览会&#xff08;简称“长三角文博会”&#xff09;在上海国家会展中心盛大启幕。长三角文博会自2018年起已成功举办多届&#xff0c;已成为展示区域文化产业发展成果、推动…