如何搭建公司内部网站,网站建设淘宝客模板下载,wordpress vr插件,网银在线北京网络科技有限公司博客主页#xff1a;小馒头学python
本文专栏: Python爬虫五十个小案例
专栏简介#xff1a;分享五十个Python爬虫小案例 #x1f40d;引言
猫眼电影是国内知名的电影票务与资讯平台#xff0c;其中Top100榜单是影迷和电影产业观察者关注的重点。通过爬取猫眼电影Top10…
博客主页小馒头学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 classboard-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, indexFalse)数据清洗与存储
在爬取数据之后我们需要进行数据清洗确保抓取的数据是准确和完整的。例如
清理电影名称中的空格和特殊字符处理评分字段中缺失或非数字的情况上映时间可能需要转换为标准日期格式
使用pandas可以方便地进行数据清洗
# 清洗数据去除空值
df.dropna(inplaceTrue)# 转换上映时间为标准格式
df[release_time] pd.to_datetime(df[release_time], errorscoerce)# 处理评分数据将评分转换为浮动类型
df[score] pd.to_numeric(df[score], errorscoerce)数据分析与可视化
通过简单的数据分析我们可以查看电影评分的分布、上映年份的趋势等
import matplotlib.pyplot as plt
import seaborn as sns# 绘制评分分布图
plt.figure(figsize(8, 6))
sns.histplot(df[score], bins20, kdeTrue)
plt.title(电影评分分布)
plt.xlabel(评分)
plt.ylabel(数量)
plt.show()# 电影上映年份分布
df[release_year] df[release_time].dt.year
plt.figure(figsize(10, 6))
sns.countplot(xrelease_year, datadf)
plt.title(电影上映年份分布)
plt.xticks(rotation45)
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, headersheaders)
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], inplaceTrue) # 删除评分和上映时间为空的行# 将评分转换为数值类型无法转换的设置为NaN
df[score] pd.to_numeric(df[score], errorscoerce)# 删除评分为空的行
df.dropna(subset[score], inplaceTrue)# 将release_time列转换为数值类型的年份
df[release_year] pd.to_numeric(df[release_time], errorscoerce)# 输出清洗后的数据
print(清洗后的数据)
print(df.head())# 保存数据为CSV文件
df.to_csv(maoyan_top100.csv, indexFalse)# 数据分析电影评分分布
plt.figure(figsize(8, 6))
sns.histplot(df[score], bins20, kdeTrue)
plt.title(电影评分分布)
plt.xlabel(评分)
plt.ylabel(数量)
plt.show()# 数据分析电影上映年份分布
plt.figure(figsize(10, 6))
sns.countplot(xrelease_year, datadf)
plt.title(电影上映年份分布)
plt.xticks(rotation45)
plt.xlabel(年份)
plt.ylabel(电影数量)
plt.show()# 结束
print(爬取和分析完成数据已保存至 maoyan_top100.csv)翻页功能
我们完成了基本的功能接下来我们为了爬取前100个电影即10页数据你需要构造爬虫来遍历每一页并合并数据。每一页的URL格式为https://www.maoyan.com/board/4?offsetn其中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, headersheaders)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], inplaceTrue) # 删除评分和上映时间为空的行# 将评分转换为数值类型无法转换的设置为NaN
df[score] pd.to_numeric(df[score], errorscoerce)# 删除评分为空的行
df.dropna(subset[score], inplaceTrue)# 将release_time列转换为数值类型的年份
df[release_year] pd.to_numeric(df[release_time], errorscoerce)# 输出清洗后的数据
print(清洗后的数据)
print(df.head())# 保存数据为CSV文件
df.to_csv(maoyan_top100.csv,encodingutf-8-sig ,indexFalse)# 数据分析电影评分分布
plt.figure(figsize(8, 6))
sns.histplot(df[score], bins20, kdeTrue)
plt.title(电影评分分布)
plt.xlabel(评分)
plt.ylabel(数量)
plt.show()# 数据分析电影上映年份分布
plt.figure(figsize(10, 6))
sns.countplot(xrelease_year, datadf)
plt.title(电影上映年份分布)
plt.xticks(rotation45)
plt.xlabel(年份)
plt.ylabel(电影数量)
plt.show()# 结束
print(爬取和分析完成数据已保存至 maoyan_top100.csv)遍历10页
我们使用range(0, 100, 10)来设置偏移量依次爬取从offset0到offset90的URL每一页的URL由base_url.format(offset)生成。
随机延迟
为了避免频繁请求导致被封禁爬虫请求每一页后加入了time.sleep(random.uniform(1, 3))模拟随机延迟
爬取并合并数据
所有电影信息都会存储到movies列表中最后通过pandas的DataFrame进行数据整合
运行结果
下图展示了电影评分分布情况还有电影上映年份的分布
结语
通过本篇博客我们展示了如何使用Python爬虫技术抓取猫眼电影Top100的数据并进行简单的数据清洗与分析。除了数据抓取和分析我们还学习了如何应对反爬虫机制。通过这些知识我们可以很好的进行后续的数据分析或者可以查看自己喜欢哪个电影当然本节主要还是为了练手为了后续我们进行其他项目任务
若感兴趣可以访问并订阅我的专栏Python爬虫五十个小案例https://blog.csdn.net/null18/category_12840403.html?fromshareblogcolumnsharetypeblogcolumnsharerId12840403sharereferPCsharesourcenull18sharefromfrom_link