Python爬虫抓取豆瓣TOP250数据

作者:蒋星熠Jaxonic日期:2025/10/28

目录

一、开门见山,探究网页结构

二、确定思路

1.拿到页面源代码/响应

2.编写正则,提取页面数据

3.保存数据

三、步骤详解

1.初步爬取

2.绕过反爬

3.编写正则表达式与正则匹配

4.翻页爬取

5.注意点


🌟 Hello,我是蒋星熠Jaxonic! 🌈 在浩瀚无垠的技术宇宙中,我是一名执着的星际旅人,用代码绘制探索的轨迹。 🚀 每一个算法都是我点燃的推进器,每一行代码都是我航行的星图。 🔭 每一次性能优化都是我的天文望远镜,每一次架构设计都是我的引力弹弓。 🎻 在数字世界的协奏曲中,我既是作曲家也是首席乐手。让我们携手,在二进制星河中谱写属于极客的壮丽诗篇!


一、开门见山,探究网页结构

在爬取之前我们要确定需要的数据究竟是在页面源代码里,还是不在页面源代码里(是不是一次性全加载进来的),如果页面源代码里没有想要的数据,说明还有其它请求获取的数据。

让我们打开页面:

右键查看页面源代码,Ctrl+/页面搜索关键词:肖申克

可以看到这时候我们需要的数据是都在页面源代码里的,验证了我们的想法:该页面数据是一次性全加载进来的,因此得到以下思路。


二、确定思路

1.拿到页面源代码/响应

2.编写正则,提取页面数据

3.保存数据


三、步骤详解

1.初步爬取

1.1 确定请求方式

接下来按F12,进入开发者工具看看怎么个事儿,发现有个Top250(这个就是第一页的页面url链接,即响应就是页面源代码

1.2 引入request模块

发现这里的请求是Get,因此引入request模块,导入request.get(页面链接)

1import requests
2
3url="https://movie.douban.com/top250"
4
5resp=requests.get(url)  #获取对应页面url的请求响应
6
7pageSource=resp.text   #把页面源代码输出
8
9print(pageSource)  #打印

这时候运行发现结果是空的:

2.绕过反爬

2.1 加入请求头

说明缺少一个反爬的验证,浏览器自动拦截了,这时候需要加一个请求头

1import requests
2
3url="https://movie.douban.com/top250"
4
5headers={
6
7"user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36 Edg/141.0.0.0"
8
9}
10resp=requests.get(url,headers=headers)
11
12pageSource=resp.text
13
14print(pageSource)

这样就可以了:

3.编写正则表达式与正则匹配

3.1 编写正则表达式

接下来就需要进行数据分离:

引入re模块,编写正则表达式:

首先从标题开始提取,从<div class="item">为开头,目标是第二个框里的文字内容,这时候需要用到惰性匹配:.*?

3.2 对比表格

特性.* (贪婪).*? (非贪婪/懒惰)
核心原则匹配尽可能的字符匹配尽可能的字符
别名贪婪模式非贪婪模式、懒惰模式、最小匹配模式
回溯行为先吃到尾,再往回找吃一个看一次,满足就停
示例文本Hello "World" and "Universe"Hello "World" and "Universe"
正则".*"".*?"
匹配结果一个结果:"World" and "Universe"两个结果:"World" 和 "Universe"
适用场景匹配大块的、从开始标志到结束标志之间的所有内容匹配多个、成对标签/引号之间的单个内容

这里样例的惰性匹配的结果是两个结果的额原因是开启了全局模式

没有 g 标志:

  • 引擎在找到第一个匹配项后就停止。

g 标志:

  • 引擎在找到第一个匹配项后,会从上次匹配结束的位置开始,继续寻找下一个匹配项。

但是这里还有一个坑,那就是.在匹配的时候是跳过所有非换行符的内容

而re.S可以让正则表达式中的.匹配换行符

1#编写正则表达式
2re.compile(r'<div class="item">.*?<span class="title">(?P<name>.*?)</span>',re.S)

3.3 进行正则匹配

接下来进行正则匹配:

1#进行正则匹配
2result=obj.finditer(pageSource)
3for item in result:
4    print(item.group("name"))

然后根据上面的规则对源代码进行匹配:

1#编写正则表达式
2obj=re.compile(r'<div class="item">.*?<span class="title">(?P<name>.*?)</span>.*?<div class="bd">'
3               r'.*?<p>.*?导演: (?P<dao>.*?)&nbsp;'
4               r'.*?<br>(?P<year>.*?)&nbsp;.*?<span class="rating_num" property="v:average">(?P<score>.*?)</span>'
5               r'.*?<span>(?P<num>.*?)人评价</span>',re.S)
6
7#进行正则匹配
8result=obj.finditer(pageSource)
9for item in result:
10    name=item.group("name")
11    dao=item.group("dao")
12    year = item.group("year").strip()   #去掉字符串两侧的空白
13    score = item.group("score")
14    num = item.group("num")
15    print(name,dao,year,score,num)

得到了结果:

3.4 保存文件

接下来保存为文件:

f=open("top250.csv",mode="w",encoding='utf-8')

导出数据:

1f.write(f"{name}{dao}{year}{score}{num}\n")
2

爬取一页的完整代码:

1# 思路:
2#
3# 1.拿到页面源代码
4#
5# 2.编写正则,提取页面数据
6#
7# 3.保存数据
8
9import requests
10import re
11
12f=open("top250.csv",mode="w",encoding='utf-8')
13
14
15url="https://movie.douban.com/top250"
16
17headers={
18
19"user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36 Edg/141.0.0.0"
20
21}
22resp=requests.get(url,headers=headers)
23resp.encoding="utf-8"  #解决乱码问题
24pageSource=resp.text
25
26#编写正则表达式
27obj=re.compile(r'<div class="item">.*?<span class="title">(?P<name>.*?)</span>.*?<div class="bd">'
28               r'.*?<p>.*?导演: (?P<dao>.*?)&nbsp;'
29               r'.*?<br>(?P<year>.*?)&nbsp;.*?<span class="rating_num" property="v:average">(?P<score>.*?)</span>'
30               r'.*?<span>(?P<num>.*?)人评价</span>',re.S)
31
32#进行正则匹配
33result=obj.finditer(pageSource)
34for item in result:
35    name=item.group("name")
36    dao=item.group("dao")
37    year = item.group("year").strip()   #去掉字符串两侧的空白
38    score = item.group("score")
39    num = item.group("num")
40    f.write(f"{name}{dao}{year}{score}{num}\n")
41    print(name,dao,year,score,num)
42
43
44f.close()
45resp.close()
46
47print("豆瓣Top250提取完毕")
48

这时候思考,现在的代码只能爬取一页的25条信息,如何爬取全部250条?

4.翻页爬取

由于发现每跳转一页页面url的start都会增加25,因此得出可以用while循环来爬取全部数据

start=(页数-1)*25


四、完整代码与注意点

1.完整代码

1# 思路:
2#
3# 1.拿到页面源代码
4#
5# 2.编写正则,提取页面数据
6#
7# 3.保存数据
8
9import requests
10import re
11
12f=open("top250.csv",mode="w",encoding='utf-8')
13#start=(页数-1)*25
14page=1
15
16while page<=10:
17    url=f"https://movie.douban.com/top250?start={(page - 1) * 25}&filter="
18
19    headers={
20
21    "user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36 Edg/141.0.0.0"
22
23    }
24    resp=requests.get(url,headers=headers)
25    resp.encoding="utf-8"  #解决乱码问题
26    pageSource=resp.text
27
28    #编写正则表达式
29    obj=re.compile(r'<div class="item">.*?<span class="title">(?P<name>.*?)</span>.*?<div class="bd">'
30                   r'.*?<p>.*?导演: (?P<dao>.*?)&nbsp;'
31                   r'.*?<br>(?P<year>.*?)&nbsp;.*?<span class="rating_num" property="v:average">(?P<score>.*?)</span>'
32                   r'.*?<span>(?P<num>.*?)人评价</span>',re.S)
33
34    #进行正则匹配
35    result=obj.finditer(pageSource)
36    for item in result:
37        name=item.group("name")
38        dao=item.group("dao")
39        year = item.group("year").strip()   #去掉字符串两侧的空白
40        score = item.group("score")
41        num = item.group("num")
42        f.write(f"{name}{dao}{year}{score}{num}\n")
43        print(name,dao,year,score,num)
44    print(f"第{page}页爬取完成")
45
46    page = page + 1
47
48
49f.close()
50resp.close()
51
52print("豆瓣Top250提取完毕")

2.注意点

解释一下

url=f"https://movie.douban.com/top250?start={(page - 1) * 25}&filter="

这里的f必须要加

不加 f 的情况:

url="https://movie.douban.com/top250?start={(page - 1) * 25}&filter="

实际URL变成了:

https://movie.douban.com/top250?start={(page - 1) * 25}&filter=

注意:{(page - 1) * 25} 被当作普通字符串,而不是要计算的表达式。无论 page 是多少,URL 始终是这个固定的字符串。

豆瓣服务器收到这个请求时,看到 start={(page - 1) * 25},它不知道这是什么,通常会将其视为 start=0 或者忽略这个参数,所以每次都返回第一页的数据。


五、结果展示

成功爬取250条数据~

■ 我是蒋星熠Jaxonic!如果这篇文章在你的技术成长路上留下了印记 ■ 👁 【关注】与我一起探索技术的无限可能,见证每一次突破 ■ 👍 【点赞】为优质技术内容点亮明灯,传递知识的力量 ■ 🔖 【收藏】将精华内容珍藏,随时回顾技术要点 ■ 💬 【评论】分享你的独特见解,让思维碰撞出智慧火花 ■ 🗳 【投票】用你的选择为技术社区贡献一份力量 ■ 技术路漫漫,让我们携手前行,在代码的世界里摘取属于程序员的那片星辰大海!


Python爬虫抓取豆瓣TOP250数据》 是转载文章,点击查看原文


相关推荐


仓颉语言性能优化指南:实测对比,让鸿蒙应用运行效率提升 40%
Jinkxs2025/10/25

👋 大家好,欢迎来到我的技术博客! 💻 作为一名热爱 Java 与软件开发的程序员,我始终相信:清晰的逻辑 + 持续的积累 = 稳健的成长。 📚 在这里,我会分享学习笔记、实战经验与技术思考,力求用简单的方式讲清楚复杂的问题。 🎯 本文将围绕一个仓颉相关话题展开,希望能为你带来一些启发或实用的参考。 🌱 无论你是刚入门的新手,还是正在进阶的开发者,希望你都能有所收获! 文章目录 仓颉语言性能优化指南:实测对比,让鸿蒙应用运行效率提升 40% 🚀🌐 仓颉语言与鸿蒙生


http 状态码
扁豆的主人2025/10/23

常见响应码 5字头:服务器错误 500 Internal Server Error 一般来说,是由于服务器端的源代码出现错误导致的。 501 Not Implemented 服务器不支持当前请求所需要的某个功能。 502 Bad Gateway 网关错误,服务器尝试执行请求,但从上游无服务收到无效响应。 503 Service Unavailable 服务器当前无法处理请求,由于超载或停机维护。 504 Gateway Timeout 网关超时,请求处理时间超过了


Edge浏览器安装Vue.js devtools插件后F12开发者工具有时不显示Vue标签页
cgs1082025/10/22

Edge 浏览器插件下载地址:https://microsoftedge.microsoft.com/addons/search/vue?hl=en-US 安装 Vue.js devtools 和 Vue Devtools Unlocker,如下图:


2025年远程控制软件横评:UU远程、ToDesk、向日葵
攻城狮7号2025/10/20

> 💡 原创经验总结,禁止AI洗稿!转载需授权 > 声明:本文所有观点均基于多个远控软件实测总结,数据说话,拒绝空谈! public class SelfIntroduction { public static String introduceMyself() { String name = "攻城狮7号"; String role = "Tech Enthusiast"; String[] likes = {"coding", "


GPT-2 中的 Pre-Layer Normalization (Pre-LN) 架构详解
mwq301232025/10/19

GPT-2 中的 Pre-Layer Normalization (Pre-LN) 架构详解 1. 概述 Pre-Layer Normalization (Pre-LN) 是一种对原始 Transformer 架构的重要改进。顾名思义,它的核心思想是将层归一化 (Layer Normalization) 操作从残差连接之后移动到每个子层(如自注意力、前馈网络)的之前。 这一看似微小的结构调整,却极大地提升了深度 Transformer 模型训练的稳定性,有效缓解了梯度消失或爆炸的问题。GPT-2


管理 Claude code上下文:实用手册
是魔丸啊2025/10/18

转载 Anthropic 的 Claude 代码和更广泛的 Claude 系列现在为开发者提供了前所未有的控制能力,可以控制模型看到的内容量和推理深度。最近的产品更新(特别是 Sonnet 4 的 100 万 token 上下文窗口和 Claude 扩展的"思考"控制)使上下文管理变得更加强大和重要:您可以在单个会话中处理整个代码库——但前提是您需要有意地构建提示、文件和会话状态。本文解释了如何可靠地管理 Claude 代码的上下文:命令和用法、思考预算控制、CLAUDE.md 模式、子代理工作


Nx带来极致的前端开发体验——任务缓存
西陵2025/10/16

前言 前面我们讲过,为了提高项目的构建速度,社区将大部分的精力放到构建工具上,例如rspack、esbuild、swc等,利用语言优势提升构建速度。而像 webpack 这种老牌构建工具则将优化方向放在缓存上,但是他缓存的是构建流程中的中间结果,例如每个文件经过 loader 转换后的产物。 而本章节要介绍的任务缓存是指缓存任务执行之后的产物,例如构建或者测试任务,对于一个 package 来说,如果他的代码没发生改变,下一次执行 build 命令时可以直接读取上一次的构建产物,而无需再次进行构


excel中关联word邮件合并使用
山西璟绘地理信息有限责任公司2025/10/15

你在日上的工作中是不是需要批量的输出格式相同但是局部需要替换的文档,如果是几份就是人工修改一下,但是如果你面对的石海量的文档,你还会人工编辑吗?首先时间不容许,其次性价比特别低,如果站在打工摸鱼的角度无可厚非,但是如果你真的愿意提高效率,接下来讲的就是你需要的,开整。 这个就是典型的使用场景: 变量: 1、统一社会信用代码 2、名称 3、原法定代表人 4、现法定代表人 5、行政村盖章落款 6、日期 准备工作: 1、首先做好一个模板,如上图所示 2、建立自己的数据库,一般


Redis(61)Redis的连接数上限是多少?
Victor3562025/10/14

Redis 的连接数上限取决于系统的硬件资源、操作系统的配置以及 Redis 自身的配置。这一限制主要来自以下几个方面: 硬件资源:包括可用的 CPU、内存等。 操作系统的限制:文件描述符数量、网络连接等。 Redis 配置:最大客户端连接数配置。 Redis 配置的限制 Redis 的最大连接数由 maxclients 配置项决定。默认情况下,这个值设置为 10000。 在 redis.conf 文件中,你可以找到并修改这个配置项: maxclients 10000 或者动态配置: re


macOS 内核路由表操作:直接 API 编程指南
liulilittle2025/10/12

🖧 macOS 内核路由表操作:直接 API 编程指南 本文将探讨如何在 macOS 系统中,通过直接调用系统 API 来高效添加和删除内核路由表项,避免调用外部命令带来的性能开销,并提供完整的 C++ 实现代码。 🧭 概述 在 macOS(基于 BSD 内核)系统中,路由表管理是网络编程的核心组成部分。传统上,管理员和开发者通常使用 route 命令或 netstat 工具来查看和管理路由表。然而,对于需要高性能网络控制的应用程序(如网络优化工具或自定义路由解决方案),直接通过系统

首页编辑器站点地图

Copyright © 2025 聚合阅读

License: CC BY-SA 4.0