当前位置: 首页 > news >正文

第一个爬虫程序:用 Requests+BeautifulSoup 抓取豆瓣电影 Top250

对于刚入门 Python 爬虫的新手来说,“抓取豆瓣电影 Top250” 是一个绝佳的入门项目 —— 它数据结构清晰、反爬压力小,且能覆盖爬虫核心流程(请求网页、解析数据、存储结果)。本文将带你从零开始,用Requests(发送 HTTP 请求)和BeautifulSoup(解析 HTML)实现这个爬虫,全程代码可复现,新手也能轻松上手。

一、前期准备:明确目标与搭建环境

在写代码前,我们需要先理清 “做什么” 和 “用什么工具”。

1. 明确爬取目标

我们要从豆瓣电影 Top250 页面(https://movie.douban.com/top250 )中提取以下关键信息,最终整理成结构化数据(如 CSV 表格):

  • 电影名称(中文)
  • 电影评分
  • 评价人数
  • 导演与主演
  • 上映时间与地区
  • 剧情简介

2. 搭建开发环境

需要安装两个核心 Python 库,直接用pip命令即可:

  • Requests:用于向豆瓣服务器发送 HTTP 请求,获取网页源代码。
  • BeautifulSoup4:用于解析获取到的 HTML 代码,提取我们需要的数据。

打开终端 / 命令提示符,输入以下命令安装:

bash

pip install requests beautifulsoup4

如果提示 “pip 不是内部命令”,需先检查 Python 环境变量是否配置(新手建议直接安装 Anaconda,自带 pip 和常用库)。

二、分析目标网页:找到数据规律

在写爬虫前,必须先 “读懂” 网页 —— 知道数据藏在 HTML 的哪个位置,以及分页规律。

1. 分析分页规律

豆瓣电影 Top250 共 10 页,每页 25 部电影。我们观察 URL 就能发现规律:

  • 第 1 页:https://movie.douban.com/top250?start=0&filter= (start=0表示从第 0 部开始)
  • 第 2 页:https://movie.douban.com/top250?start=25&filter= (start=25表示从第 25 部开始)
  • 第 3 页:https://movie.douban.com/top250?start=50&filter=
  • ...
  • 第 10 页:https://movie.douban.com/top250?start=225&filter= (start=225,225+25=250)

因此,只需循环修改start参数(0、25、50...225),就能爬取所有页面。

2. 定位数据在 HTML 中的位置

要提取数据,需先找到数据对应的 HTML 标签。以 “电影名称” 和 “评分” 为例:

  1. 打开豆瓣 Top250 第 1 页,右键点击 “查看网页源代码”(或按 F12 打开开发者工具)。
  2. Ctrl+F搜索关键词(如 “肖申克的救赎”),找到对应 HTML 结构:

html

<div class="item">  <!-- 每部电影的信息都包裹在class为"item"的div中 --><div class="info"><div class="hd"><a href="https://movie.douban.com/subject/1292052/" class=""><span class="title">肖申克的救赎</span>  <!-- 中文电影名 --><span class="title">&nbsp;/&nbsp;The Shawshank Redemption</span>  <!-- 外文片名(可选) --></a></div><div class="bd"><div class="star"><span class="rating_num" property="v:average">9.7</span>  <!-- 评分 --><span property="v:best" content="10.0"></span><span class="japanese" property="v:votes">2754844</span>  <!-- 评价人数 --></div><p class="">导演: 弗兰克·德拉邦特 Frank Darabont&nbsp;&nbsp;&nbsp;主演: 蒂姆·罗宾斯 Tim Robbins...  <!-- 导演+主演 --><br>1994&nbsp;/&nbsp;美国&nbsp;/&nbsp;犯罪 剧情  <!-- 上映时间+地区+类型 --></p><p class="quote"><span class="inq">希望是件好东西,也许是世上最好的东西,好东西是永远不会消逝的。</span>  <!-- 剧情简介 --></p></div></div>
</div>

规律很清晰:每部电影的信息都在class="item"的 div 内,我们只需定位到这个 div,再逐层提取子标签中的数据即可。

三、核心代码实现:分三步走

爬虫的核心流程可分为 “请求网页→解析数据→存储数据”,我们按步骤编写代码。

1. 第一步:发送请求,获取网页源代码

requests.get()发送 HTTP 请求,注意需要设置headers模拟浏览器(否则豆瓣会拒绝爬虫请求)。

代码片段:获取单页源代码

python

import requests
from bs4 import BeautifulSoup
import csv  # 用于存储数据到CSV文件
import time  # 用于设置请求间隔,避免被封IPdef get_page_html(url):"""功能:根据URL发送请求,返回网页的HTML源代码参数:url - 目标网页的URL返回:html_text - 网页源代码(字符串)"""# 设置headers:模拟浏览器请求(替换成你自己的User-Agent)headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"}try:# 发送GET请求response = requests.get(url, headers=headers)# 检查请求是否成功(状态码200表示成功)if response.status_code == 200:# 设置编码为UTF-8,避免中文乱码response.encoding = "utf-8"return response.textelse:print(f"请求失败,状态码:{response.status_code}")return Noneexcept Exception as e:# 捕获请求过程中的异常(如网络错误)print(f"请求出错:{e}")return None

关键说明

  • User-Agent:告诉豆瓣服务器 “我是浏览器,不是爬虫”。你可以在浏览器开发者工具的 “Network”→任意请求→“Request Headers” 中找到自己的User-Agent,直接复制替换。
  • 异常处理:用try-except捕获网络错误,用status_code判断请求是否成功,避免程序崩溃。

2. 第二步:解析 HTML,提取目标数据

BeautifulSoup解析获取到的 HTML 代码,按之前分析的标签结构提取数据。

代码片段:解析单页数据

python

def parse_page_html(html_text):"""功能:解析HTML源代码,提取单页电影数据参数:html_text - 网页源代码返回:movie_list - 单页电影数据列表(每个元素是字典)"""# 初始化BeautifulSoup对象,指定解析器为lxml(需安装:pip install lxml)soup = BeautifulSoup(html_text, "lxml")# 定位所有电影项(class="item"的div)item_list = soup.find_all("div", class_="item")movie_list = []for item in item_list:# 1. 提取电影名称(中文)title_tag = item.find("span", class_="title")  # 第一个title标签是中文名称movie_title = title_tag.get_text() if title_tag else "未知名称"# 2. 提取评分rating_tag = item.find("span", class_="rating_num")movie_rating = rating_tag.get_text() if rating_tag else "0.0"# 3. 提取评价人数votes_tag = item.find("span", property="v:votes")movie_votes = votes_tag.get_text() if votes_tag else "0"# 4. 提取导演与主演(需处理字符串格式)info_tag = item.find("div", class_="bd").find("p", class_="")info_text = info_tag.get_text(strip=True) if info_tag else ""  # strip()去除多余空格# 分割导演和主演(格式:"导演: XXX 主演: XXX")if "导演:" in info_text:director_part = info_text.split("主演:")[0].replace("导演:", "").strip()actor_part = info_text.split("主演:")[-1].strip() if "主演:" in info_text else "未知"else:director_part = "未知导演"actor_part = "未知主演"movie_director = director_partmovie_actor = actor_part# 5. 提取上映时间、地区、类型(从info_text的第二行提取)info_lines = info_text.split("\n")  # 按换行符分割if len(info_lines) >= 2:year_area_genre = info_lines[1].strip()  # 第二行格式:"1994 / 美国 / 犯罪 剧情"year = year_area_genre.split("/")[0].strip() if "/" in year_area_genre else "未知年份"area = year_area_genre.split("/")[1].strip() if len(year_area_genre.split("/")) >=2 else "未知地区"else:year = "未知年份"area = "未知地区"movie_year = yearmovie_area = area# 6. 提取剧情简介quote_tag = item.find("span", class_="inq")movie_quote = quote_tag.get_text() if quote_tag else "无简介"# 整理单部电影数据为字典movie_dict = {"电影名称": movie_title,"评分": movie_rating,"评价人数": movie_votes,"导演": movie_director,"主演": movie_actor,"上映年份": movie_year,"地区": movie_area,"剧情简介": movie_quote}movie_list.append(movie_dict)return movie_list

关键说明

  • soup.find():查找第一个匹配的标签;soup.find_all():查找所有匹配的标签。
  • get_text():提取标签内的文本内容;strip():去除文本前后的空格、换行符。
  • 数据容错:用if...else判断标签是否存在,避免因部分电影信息缺失导致程序报错(如某些电影没有简介)。

3. 第三步:存储数据,写入 CSV 文件

将提取的所有电影数据写入 CSV 文件,方便后续查看和分析(比纯文本更结构化)。

代码片段:存储数据与主函数

python

def save_to_csv(movie_all, filename):"""功能:将所有电影数据写入CSV文件参数:movie_all - 所有电影数据列表;filename - 输出文件名"""# 定义CSV文件的表头(与movie_dict的键对应)headers = ["电影名称", "评分", "评价人数", "导演", "主演", "上映年份", "地区", "剧情简介"]# 打开文件,使用utf-8-sig编码避免中文乱码,newline=''避免空行with open(filename, "w", encoding="utf-8-sig", newline="") as f:writer = csv.DictWriter(f, fieldnames=headers)writer.writeheader()  # 写入表头writer.writerows(movie_all)  # 写入所有数据print(f"数据已成功保存到 {filename}")def main():"""主函数:统筹整个爬虫流程(分页请求→解析→汇总数据→保存)"""movie_all = []  # 存储所有页面的电影数据base_url = "https://movie.douban.com/top250?start={}&filter="  # 基础URL,start参数动态替换# 循环爬取10页(start从0到225,步长25)for start in range(0, 250, 25):print(f"正在爬取第 {start//25 + 1} 页...")url = base_url.format(start)  # 生成当前页的URLhtml_text = get_page_html(url)  # 获取当前页HTMLif html_text:page_movies = parse_page_html(html_text)  # 解析当前页数据movie_all.extend(page_movies)  # 将当前页数据加入总列表# 设置1秒间隔,避免请求过于频繁被封IPtime.sleep(1)# 保存所有数据到CSV文件save_to_csv(movie_all, "豆瓣电影Top250.csv")print(f"爬虫结束,共抓取到 {len(movie_all)} 部电影数据")# 程序入口:当脚本直接运行时,执行main()函数
if __name__ == "__main__":main()

四、运行程序与查看结果

  1. 将上述三段代码合并为一个 Python 文件(如douban_top250_spider.py)。
  2. 替换代码中的User-Agent为你自己的(否则可能请求失败)。
  3. 运行脚本:在终端输入python douban_top250_spider.py

预期结果:

  • 终端会输出爬取进度:正在爬取第 1 页...正在爬取第 10 页...
  • 脚本所在目录会生成豆瓣电影Top250.csv文件,用 Excel 或 WPS 打开后,数据如下(示例):
电影名称评分评价人数导演主演上映年份地区剧情简介
肖申克的救赎9.72754844弗兰克・德拉邦特蒂姆・罗宾斯 摩根・弗里曼1994美国希望是件好东西,也许是世上最好的东西...
霸王别姬9.62025807陈凯歌张国荣 张丰毅 巩俐1993中国大陆说的是一辈子!差一年,一个月,一天...

五、爬虫伦理与注意事项

作为新手,必须遵守爬虫伦理,避免给目标网站造成负担或触犯法律:

  1. 设置请求间隔:代码中time.sleep(1)表示每爬一页停 1 秒,避免高频请求导致 IP 被封。
  2. 遵守 Robots 协议:访问https://movie.douban.com/robots.txt ,确认豆瓣是否允许爬取 Top250(目前豆瓣允许非商业用途的温和爬取)。
  3. 数据用途:仅用于个人学习,不得将爬取的数据用于商业用途或公开传播。
  4. 避免过度爬取:本项目仅爬取 250 条数据,规模小,不会对豆瓣服务器造成压力。

六、总结与拓展

通过这个项目,你已经掌握了 Python 爬虫的核心流程:

  • Requests发送 HTTP 请求,处理异常;
  • BeautifulSoup解析 HTML,定位和提取数据;
  • CSV存储结构化数据。

如果想进一步提升,可以尝试这些拓展方向:

  1. 数据可视化:用matplotlibseaborn绘制评分分布、地区电影数量柱状图。
  2. 多线程爬取:用threadingconcurrent.futures加快爬取速度(注意控制线程数,避免给服务器造成压力)。
  3. 存储到数据库:将数据写入MySQLMongoDB,学习数据库操作。

希望这篇教程能帮你顺利写出第一个爬虫程序,开启 Python 数据采集的大门!

http://www.dtcms.com/a/473989.html

相关文章:

  • JavaScript 企业面试与学习难度拆解:从0到中高级的阶梯式路线图
  • 北京互联网公司有多少家seo词条
  • 网站项目建设所需成本网站前端建设需要学会什么
  • 拌合站软件开发(25) 替换海康LED屏幕可行性分析及方案
  • 外贸公司网站改版思路汉中网站网站建设
  • 物联网和嵌入式开发中使用16进制的原因
  • 自己制作网站的方法是服务器怎样做网站呢
  • 制作网站注册登录模块的思维导图今天的新闻联播
  • 映诗:基于视觉编码与自然语言生成的作诗平台
  • 《深入理解 SQLAlchemy 引擎与会话:从 Core 到 ORM 的全景解析》
  • Redis渐进式遍历:安全高效的键扫描术
  • Java-集合练习2
  • sql优化之联合索引
  • 基于51单片机无线八路抢答器
  • 网站怎么做白色字阿里巴巴网站官网
  • 2.3进程同步与互斥
  • 计算机组成原理之第一章计算机系统概述
  • 无服务器架构下的ACID特性实现方案
  • 四平方和定理
  • 搜索郑州网站服装网站建设
  • 广西临桂建设局网站如何做家乡网站
  • Leetcode2166-设计位集
  • 三种方法解——力扣206.反转链表
  • 企业网站广告网站响应式是什么意思
  • 湖南省郴州市邮编东莞seo网站建设公司
  • 差分信号可以分解为共模信号与差模信号
  • **标题:发散创新:探索SSR渲染技术的深度实现****摘要**:本文将深入探讨服务端渲染(SSR)技术的原理、优势以及实
  • 计算机视觉(opencv)——MediaPipe 实现手部关键点检测与可视化
  • 贵州省建设学校官方网站昆明网络公司开发
  • 没有版权可以做视频网站吗设计之家素材