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

请添加图片描述

博客主页:小馒头学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 randomheaders = {'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)  # 构造每一页的URLresponse = requests.get(url, headers=headers)response.encoding = 'utf-8'# 使用BeautifulSoup解析HTMLsoup = 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.mzph.cn/news/888093.shtml

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

相关文章

springboot信息化在线教学平台的设计与实现(代码+数据库+LW)

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了信息化在线教学平台的开发全过程。通过分析信息化在线教学平台管理的不足&#xff0c;创建了一个计算机管理信息化在线教学平台的方案。文章介绍了信息化在线教…

Hadoop批量计算实验

参考: Hadoop(一)之实验一CentOS7配置Hadoop系统:配置CentOS和下载安装包_基于虚拟机cents7搭建hadoop实验目的-CSDN博客 --------------------------------------------------------- 一、安装Vmware 二、创建虚拟机 1.安装centos7 ①打开VMware,点击新建虚拟机。 …

Flink四大基石之Time (时间语义) 的使用详解

目录 一、引言 二、Time 的分类及 EventTime 的重要性 Time 分类详述 EventTime 重要性凸显 三、Watermark 机制详解 核心原理 Watermark能解决什么问题,如何解决的? Watermark图解原理 举例 总结 多并行度的水印触发 Watermark代码演示 需求 代码演示&#xff…

Ubuntu 操作系统

一、简介 Ubuntu 是一个基于 Linux 的开源操作系统&#xff0c;它由 Canonical Ltd. 公司维护和资助。Ubuntu 以其易用性、强大的社区支持和定期的安全更新而闻名&#xff0c;一个一桌面应用为主的操作系统。 二、用户使用 1、常规用户的登陆方式 在登录时一般使用普通用户&…

Apifox Echo - 简单而强大的API测试服务

什么是Apifox Echo? Apifox Echo 是由 Apifox 官方推出的一个专业的接口请求和返回数据服务平台。它的主要目的是帮助开发人员和测试人员更好地学习和测试API接口。 核心特点 简单易用 提供简洁的HTTP请求和响应服务操作界面直观,上手容易服务地址统一: https://echo.api…

Linux笔记---进程:进程等待

1. 进程等待的概念 进程等待是指父进程通过系统调用wait或waitpid来对子进程进行状态检测与回收的功能。 当子进程退出时&#xff0c;如果父进程不读取子进程的退出状态&#xff0c;子进程就会成为僵尸进程&#xff0c;造成内存泄漏的问题。因此&#xff0c;父进程需要调用wa…

常见靶场的搭建

漏洞靶场 渗透测试&#xff08;漏洞挖掘&#xff09;切忌纸上谈兵&#xff0c;学习渗透测试&#xff08;漏洞挖掘&#xff09;知识的过程中&#xff0c;我们通常需要一个包含漏洞的测试环境来进行训练。而在非授权情况下&#xff0c;对于网站进行渗透测试攻击&#xff0c;是触及…

AtomicIntegerFieldUpdater能否降低内存

1. 代码如下&#xff1a; import java.util.LinkedList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger;public class AtomicIntegerTest {final AtomicInteger startPosition new AtomicInteger(0);final AtomicInteger wrotePosition new Atom…

从零开始:使用Vite和pnpm搭建Vue3项目实战指南

目录 一、Node.js的下载和安装 1、打开Node.js官网&#xff08;Node.js — Run JavaScript Everywhere&#xff09; 2、点击下载按钮&#xff0c;下载完成后&#xff0c;打开文件&#xff0c;一直按Next按钮&#xff0c;直到 3、下载完成后,找到文件所在位置&#xff0c;然…

立创庐山派 K230 RTSP 推流

立创庐山派使用的是K230芯片&#xff0c;按照教程刷了canmv固件&#xff0c;下载canmv ide&#xff0c;使用嘉楠社区的rtsp和wlan例程&#xff0c;修改成连接wifi以及RTSP推流例程 # Description: This example demonstrates how to stream video and audio to the network us…

数据湖的概念(包含数据中台、数据湖、数据仓库、数据集市的区别)--了解数据湖,这一篇就够了

文章目录 一、数据湖概念1、企业对数据的困扰2、什么是数据湖3、数据中台、数据湖、数据仓库、数据集市的区别 网上看了好多有关数据湖的帖子&#xff0c;还有数据中台、数据湖、数据仓库、数据集市的区别的帖子&#xff0c;发现帖子写的都很多&#xff0c;而且专业名词很多&am…

springboot kafka在kafka server AUTH变动后consumer自动销毁

前言 笔者使用了kafka用来传输数据&#xff0c;笔者在今年10月写了文章&#xff0c;怎么使用配置化实现kafka的装载&#xff1a;springboot kafka多数据源&#xff0c;通过配置动态加载发送者和消费者-CSDN博客 不过在实际运行中&#xff0c;kafka broker是加密的&#xff0c…

在Windows下编译支持https的wsdl2h

下载源码 在官网下载源码 安装Openssl 下载OpenSSL并安装&#xff0c;安装完成后需要将OpenSSL的路径添加到环境变量中 配置VS 1、打开工程 2、因为前面安装的OpenSLL是64位的&#xff0c;因此需要创建一个X64的配置 打开配置管理器&#xff0c;然后选择新建&#xff0…

【Webgl_glslThreejs】制作流水效果/毛玻璃效果材质

效果预览 shadertory源码 source&#xff1a; https://www.shadertoy.com/view/lldyDs 材质代码 import { DoubleSide, ShaderChunk, ShaderMaterial, TextureLoader } from "three"; /** * * source https://www.shadertoy.com/view/lldyDs */export default fu…

vue3+ts+uniapp微信小程序顶部导航栏

这是colorui改的&#xff0c;不用就不用看啦 color-ui(https://docs.xzeu.com/#/) 新建component文件夹创建topNavigation.vue <template><view><view class"cu-custom" :style"height: CustomBar px"><view class"cu-bar…

openssl使用哈希算法生成随机密钥

文章目录 一、openssl中随机数函数**OpenSSL 随机数函数概览**1. **核心随机数函数** **常用函数详解**1. RAND_bytes2. RAND_priv_bytes3. RAND_seed 和 RAND_add4. RAND_status **随机数生成器的熵池****常见用例****注意事项** 二、使用哈希算法生成随机的密钥 一、openssl中…

刷题日常(找到字符串中所有字母异位词,​ 和为 K 的子数组​,​ 滑动窗口最大值​,全排列)

找到字符串中所有字母异位词 给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 题目分析&#xff1a; 1.将p里面的字符先丢进一个hash1中&#xff0c;只需要在S字符里面找到多少个和他相同的has…

【汇编语言】call 和 ret 指令(三) —— 深度解析汇编语言中的批量数据传递与寄存器冲突

文章目录 前言1. 批量数据的传递1.1 存在的问题1.2 如何解决这个问题1.3 示例演示1.3.1 问题说明1.3.2 程序实现 2. 寄存器冲突问题的引入2.1 问题引入2.2 分析与解决问题2.2.1 字符串定义方式2.2.2 分析子程序功能2.2.3 得到子程序代码 2.3 子程序的应用2.3.1 示例12.3.2 示例…

前端的面试题

1.常用的块与行属性内标签有哪些&#xff1f;有什么特征&#xff1f; 块标签&#xff1a;div、h1~h6、ul、li、table、p、br、form。 特征&#xff1a;独占一行&#xff0c;换行显示&#xff0c;可以设置宽高&#xff0c;可以嵌套块和行 行标签&#xff1a;span、a、img、text…

48-基于单片机的LCD12864时间调控和串口抱站

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机的公交报站系统&#xff0c;可以手动报站&#xff0c;站名十个。 在lcd12864上显示时间&#xff08;年月日时分秒&#xff09;和站名&#xff0c;时间可以设置&#xff0c; 仿真中可以…