解锁豆瓣高清海报(三)从深度爬虫到URL构造,实现极速下载

脚本地址:

项目地址: Gazer

PosterBandit_v2.py

前瞻

之前的 PosterBandit.py 是按照深度爬虫的思路一步步进入海报界面来爬取, 是个值得学习的思路, 但缺点是它爬取慢, 仍然容易碰到豆瓣的 418 错误, 本文也会指出彻底解决旧版 418 错误的方法并提高爬取速度. 现在我将介绍优化版, 这个版本通过直接构造 URL 来实现获取海报原图, 准确识别、更快爬取. 本文会重点讲解动态 headers 及其应用于请求的必要性.

使用方法

  1. 克隆或下载项目代码.
  2. 安装依赖: pip install requests, 或者克隆项目代码后 pip install -r requirements.txt
  3. 修改脚本内部的常量 DEFAULT_POSTER_PATH, 设置默认保存路径.
  4. 修改主函数处的 poster_save_path 保存路径.
  5. 修改主函数处的起始日期 target_date_1 和截止日期 target_date_2. 同时修改起始爬取页参数为包含截止日期标记的页数 page_id=1.
  6. 填写你的 cookies.
  7. 运行脚本 PosterBandit_v2.

注意

  • 起止日期不要写错, 否则判断逻辑会出错.
  • 见免责声明.

示例:

    target_date_1 = "2024-12-1"  # TODO 填写起始日期
    target_date_2 = "2024-12-31" # TODO 填写截止日期

文件结构

Gazer/
├── DoubanGaze/
│   ├── data/
│   │   └── poster/
│   │       └── 2024_1_1_2025_1_31/
│   └── src/
│       ├── PosterBandit.py
│       └── PosterBandit_v2.py
└──...

脚本构思详解

V2 版本处理了深度为 1 的数据 (缩略图链接) 和深度为 2 的数据 (最终海报 URL), 但它 爬取 的深度仍然是 0. 依然在括号中标记了爬取深度.

  1. 以默认第一页或指定的页数作为爬取的起始页 (爬取深度 0), 找到所有包含电影条目的 div 元素, 最大为 15 个. ▶️ get_movie_elements

    电影条目 CSS 选择器: #content > div.grid-16-8.clearfix > div.article .item.comment-item

  2. 在电影条目的 div 元素内找到对应的日期元素压缩的海报图片链接 ▶️ get_movie_info

    1. 日期 CSS 选择器: #content div.info span.date

      检查是否在指定的起止日期参数之间 ▶️ compare_date

    2. 这个页面的海报图片元素 CSS 选择器: #content div.pic img

      1. 以 <绝命毒师 第二季> 为例, 在这里 <img> 标签的 source 链接是 https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2016505705.webp (可以认为是数据深度 1, 因为它直接来源于起始页), 高清海报页面 https://movie.douban.com/photos/photo/2016505705/ 的海报元素 source 链接是 https://img9.doubanio.com/view/photo/l/public/p2016505705.webp (数据深度 2, 因为它需要通过详情页才能获取, 或者说, 如果按照 V1 的"点击"流程, 需要经过两层(收藏页 -> 电影详情页 -> 海报大图)页面跳转才能到达).

        注意: 这个 在这里插入图片描述
        div 中放了 2 个可下载图片资源链接. 首先, 后一个 jpg 链接需要通过 JS 动态加载激活, 直接下载是不可用的; 其次, 一般 WebP 文件会更小, 基于 WebP 更先进的压缩算法, 肉眼观察可能会感觉 WebP 更清晰. 所以这里第一个链接是最优选择.

      2. 观察两个链接, 可以知道, 只要在这个页面找到第一个链接, 即可构造第二个: https://img9.doubanio.com/view/photo/l/public/p{photo_id}.webp (数据深度 2, 但 V2 版本是直接构造这个 URL, 没有爬取这个深度的页面)

      检查是否在指定的起止日期参数之间 ▶️ compare_date

  3. 下载图片保存到指定路径, 创建文件夹名称, 根据日期定义, 如 2024_1_1_2024_12_31 ▶️ create_folder save_poster

爬虫效率优化

V2 版本 ( PosterBandit_v2.py ) 确实比 V1 版本 ( PosterBandit.py ) 理论上应该更快, 因为减少了不必要的请求 (不再需要进入每个电影的详情页, 直接构造海报 URL). 而且用 save_poster() 函数单独测试海报下载也是成功的, 这说明问题很可能出在 V2 版本的爬虫逻辑上, 而不是 save_poster() 函数本身.

问题:

  • V2 版本: 出现高频率 418 错误 (只能下载第一张);
  • V1 版本: (深度爬虫) 能正常下载. 但速度慢, 可能会有 418.

V1 和 V2 的主要区别 (请求层面):

  • V1 (深度爬虫):

    1. 请求豆瓣电影收藏页面 (https://movie.douban.com/people/{user_id}/collect...).
    2. 对于页面上的每个电影条目, 获取电影详情页链接.
    3. 请求每个电影详情页链接 (https://movie.douban.com/subject/{movie_id}/).
    4. 从电影详情页中获取海报列表页链接.
    5. 请求海报列表页链接 (https://movie.douban.com/subject/{movie_id}/photos...).
    6. 从海报列表页中获取第一张海报的详情页链接.
    7. 请求第一张海报的详情页链接 (https://movie.douban.com/photos/photo/{photo_id}/).
    8. 从海报详情页中获取最终的海报图片 URL.
    9. 请求最终的海报图片 URL, 下载海报.
  • V2 (构造 URL):

    1. 请求豆瓣电影收藏页面 (https://movie.douban.com/people/{user_id}/collect...).
    2. 对于页面上的每个电影条目, 获取电影的 缩略图 链接 (例如 https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2016505705.webp).
    3. 从缩略图链接中提取 photo ID.
    4. 直接构造海报图片 URL (https://img9.doubanio.com/view/photo/l/public/p{photo_id}.webp).
    5. 请求构造的海报图片 URL, 下载海报.

V2 版本高频率 418 的原因:

  1. 请求频率过高:

    • V1 的 “缓冲” 作用: V1 版本虽然请求次数多, 但每次请求之间都有一定的 “缓冲”. 它需要逐个进入电影详情页、海报列表页等, 这些页面加载本身就需要时间. 这些 “无意” 的延迟, 反而降低了请求频率, 不容易触发豆瓣的反爬机制.
    • V2 的 “集中” 请求: V2 版本大大减少了请求次数, 理论上更快. 但它把对海报图片 URL 的请求 集中 在了一起. 在循环中, 它会快速地、连续地请求多个海报图片 URL, 这很容易被豆瓣服务器识别为爬虫行为, 从而触发 418 错误 (或者其他更严厉的封禁).
  2. Referer 头的问题:

    • Referer 2 个版本, 当请求最终的海报图片 URL 时, Referer 头理应是海报详情页的 URL, 但实际都是直接请求它. 此时, Referer 头会是豆瓣电影收藏页面 URL (例如 https://movie.douban.com/people/{user_id}/collect...). 服务器可能会认为, 直接从收藏页面请求海报图片 URL 这种行为不太正常, 因为用户通常会先点击海报进入详情页, 然后再查看大图. 因此, 豆瓣可能会对这种 Referer 头的请求更加警惕.

解决: 修改后的 V2 版本代码 (重点是增加延迟和修改 Referer):

主要修改:

  1. get_headers() 函数修改:

    • 参数名 viewed_movie_url 改为 referer, 更通用.
    • 函数内部使用传入的 referer 参数设置 Referer 请求头.
  2. save_poster() 函数:

    • 增加了一个 headers 参数.
    • requests.get() 中使用传入的 headers 参数.
  3. download_poster_images() 函数修改:

    • 在首次请求豆瓣电影收藏页面时, 使用 viewed_movie_url 作为 Referer.
    • 在循环内部, 构造好 headers 后, 调用 save_poster() 函数时, 传入 headers 参数.
    • 在每次循环请求海报 URL 之前, 增加 time.sleep(random.uniform(2, 6)), 随机延迟 2-6 秒或更长. 用于降低请求频率.

V1 版本代码也作了同样的修改, 测试后显著提高了速度以及避免了 418.

性能对比

对比一下, 同样的内容完整爬取, 包括延迟时间, 总耗时:

  • 38 张图片: V1 版本 5 分 29 秒, V2 版本 2 分 50 秒.
  • 110 张图片: V1 版本 15 分 10 秒, V2 版本 8 分 15 秒.

V1 版本 (深度爬虫) 的速度提升也很明显, 这说明 Referer 的正确设置确实非常重要! 豆瓣的反爬机制很可能对 Referer 做了比较严格的检查.

V2 版本 (构造 URL) 会比 V1 快近一倍. 因为 V2 版本减少了大量不必要的请求 (不需要访问每个电影的详情页和海报列表页), 直接构造最终的海报 URL, 所以速度最快.

总结:

  • 解决了 418 错误: 通过增加延迟和正确设置 Referer 头.
  • 优化了 V1 版本: 给 V1 版本增加 Referer 头更新, 提高了 V1 的速度 (从超过 5 分钟缩短到大约 2 分半钟).
    度最快.

总结:

  • 解决了 418 错误: 通过增加延迟和正确设置 Referer 头.
  • 优化了 V1 版本: 给 V1 版本增加 Referer 头更新, 提高了 V1 的速度 (从超过 5 分钟缩短到大约 2 分半钟).
  • 性能对比: 对比了 V1 和 V2 版本的性能, 验证了 V2 版本 (构造 URL) 的速度优势.

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一维差分算法篇:高效处理区间加减

那么在正式介绍我们的一维差分的原理前&#xff0c;我们先来看一下一维差分所应用的一个场景&#xff0c;那么假设我们现在有一个区间为[L,R]的一个数组&#xff0c;那么我要在这个数组中的某个子区间比如[i,m] (L<i<m<R)进行一个加k值或者减去k值的一个操作&#xff…

信息收集-Web应用JS架构URL提取数据匹配Fuzz接口WebPack分析自动化

知识点&#xff1a; 1、信息收集-Web应用-JS提取分析-人工&插件&项目 2、信息收集-Web应用-JS提取分析-URL&配置&逻辑 FUZZ测试 ffuf https://github.com/ffuf/ffuf 匹配插件 Hae https://github.com/gh0stkey/HaE JS提取 JSFinder https://github.com/Threez…

Python基础语法精要

文章目录 一、Python的起源二、Python的用途三、Python的优缺点优点缺点 四、基础语法&#xff08;1&#xff09;常量和表达式&#xff08;2&#xff09;变量变量的语法&#xff08;i&#xff09;定义变量&#xff08;ii&#xff09;变量命名的规则 &#xff08;3&#xff09;变…

测试方案整理

搜索引擎放在那里&#xff1f;研发 查看问题样本或者在提取再批量入录等情况&#xff0c;一旦我没有勾选或者全选中已经批量入录的样本&#xff0c;那么在直接点击批量提取或查看问题样本的后&#xff0c;会自动默认为选择全选样本还是按照输入错误处理&#xff1f; 批量查看返…

开启对话式智能分析新纪元——Wyn商业智能 BI 携手Deepseek 驱动数据分析变革

2月18号&#xff0c;Wyn 商业智能 V8.0Update1 版本将重磅推出对话式智能分析&#xff0c;集成Deepseek R1大模型&#xff0c;通过AI技术的深度融合&#xff0c;致力于打造"会思考的BI系统"&#xff0c;让数据价值触手可及&#xff0c;助力企业实现从数据洞察到决策执…

政策赋能科技服务,CES Asia 2025将展北京科技新貌

近日&#xff0c;《北京市支持科技服务业高质量发展若干措施》正式印发&#xff0c;为首都科技服务业的腾飞注入了强大动力。 该《若干措施》提出了三方面14条政策措施。在壮大科技服务业市场主体方面&#xff0c;不仅支持科技服务业企业向平台化和综合性服务机构发展&#xf…

2024春秋杯网络安全联赛冬季赛wp

web flask 根据题目描述&#xff0c;很容易想到ssti注入 测试一下 确实存在 直接打payload {{lipsum.globals[‘os’].popen(‘cat f*’).read()}} file_copy 看到题目名字为file_copy&#xff0c; 当输入路径时会返回目标文件的大小&#xff0c; 通过返回包&#xff0c…

Mac os部署本地deepseek+open UI界面

一.部署本地deepseek 使用ollama部署&#xff0c;方便快捷。 ollama介绍&#xff1a;Ollama 是一个高效、便捷的人工智能模型服务平台&#xff0c;提供多样化的预训练模型&#xff0c;涵盖自然语言处理、计算机视觉、语音识别等领域&#xff0c;并支持模型定制和微调。其简洁…

分布式技术

一、为什么需要分布式技术&#xff1f; 1. 科学技术的发展推动下 应用和系统架构的变迁&#xff1a;单机单一架构迈向多机分布式架构 2. 数据大爆炸&#xff0c;海量数据处理场景面临问题 二、分布式系统概述 三、分布式、集群 四、负载均衡、故障转移、伸缩性 负载均衡&a…

基于ssm的超市订单管理系统

一、系统架构 前端&#xff1a;jsp | web components | jquery | css | ajax 后端&#xff1a;spring | springmvc | mybatis 环境&#xff1a;jdk1.8 | mysql | maven | tomcat 二、代码及数据 三、功能介绍 01. 登录 02. 首页 03. 订单管理 04. 供应…

尚硅谷爬虫note004

一、urllib库 1. python自带&#xff0c;无需安装 # _*_ coding : utf-8 _*_ # Time : 2025/2/11 09:39 # Author : 20250206-里奥 # File : demo14_urllib # Project : PythonProject10-14#导入urllib.request import urllib.request#使用urllib获取百度首页源码 #1.定义一…

在nodejs中使用RabbitMQ(三)Routing、Topics、Headers

示例一、Routing exchange类型direct&#xff0c;根据消息的routekey将消息直接转发到指定队列。producer.ts 生产者主要发送消息&#xff0c;consumer.ts负责接收消息&#xff0c;同时也都可以创建exchange交换机&#xff0c;创建队列&#xff0c;为队列绑定exchange&#xff…

DeepSeek大模型一键部署解决方案:全平台多机分布式推理与国产硬件优化异构计算私有部署

DeepSeek R1 走红后&#xff0c;私有部署需求也随之增长&#xff0c;各种私有部署教程层出不穷。大部分教程只是简单地使用 Ollama、LM Studio 单机运行量化蒸馏模型&#xff0c;无法满足复杂场景需求。一些操作配置也过于繁琐&#xff0c;有的需要手动下载并合并分片模型文件&…

【腾讯地图】录入经纬度功能 - 支持地图选点

目录 效果展示代码引入地图服务地址弹框中输入框 - 支持手动输入经纬度/地图选点按钮地图选点弹框组件 当前文章 - 地图功能与 https://blog.csdn.net/m0_53562074/article/details/143677335 功能类似 效果展示 代码 引入地图服务地址 public/index.html <!-- 互联网地图…

机器学习 - 大数定律、可能近似正确学习理论

一、大数定律&#xff1a; 大数定律是概率论中的一个基本定理&#xff0c;其核心思想是&#xff1a;当独立重复的随机试验次数足够大时&#xff0c;样本的平均值会趋近于该随机变量的期望值。下面从直观和数学两个角度来说明这一概念&#xff1a; 1. 直观理解 重复试验的稳定…

算法很美笔记(Java)——树(知识点)

性质 树 上面的性质因为两个结点由一条边连成 结点数目越多&#xff0c;算法复杂度越高 二叉树 结构 层次遍历&#xff08;bfs&#xff09; 利用队列&#xff0c;弹一个&#xff0c;加N个&#xff08;队列里弹出一个元素&#xff0c;就把这个元素的所有孩子加进去&#xff…

Mediamtx+Python读取webrtc流

一、功能思路&#xff1a; 1、我采用ffmpeg -re -stream_loop -1 -i xcc.mp4 -c:v libx264 -profile:v baseline -x264opts "bframes0:repeat_headers1" -b:v 1500k -preset fast -f flv rtmp://127.0.0.1:1835/stream/111推流到mediamtx的rtmp上 2、通过mediamtx自…

数据库第三次作业

第一题&#xff1a; 学生表&#xff1a;Student (Sno, Sname, Ssex , Sage, Sdept) 学号&#xff0c;姓名&#xff0c;性别&#xff0c;年龄&#xff0c;所在系 Sno为主键 课程表&#xff1a;Course (Cno, Cname,) 课程号&#xff0c;课程名 Cno为主键 学生选课表&#xff1a;S…

「软件设计模式」单例模式

深入解析单例模式&#xff1a;从思想到C实战实现 一、设计模式与单例模式思想 1.1 设计模式的价值 设计模式是软件工程领域的经验结晶&#xff0c;如同建筑领域的经典蓝图。它们提供了经过验证的解决方案模板&#xff0c;能有效解决以下问题&#xff1a; 提高代码复用性提升…

python后端调用Deep Seek API

python后端调用Deep Seek API 需要依次下载 ●Ollama ●Deepseek R1 LLM模型 ●嵌入模型nomic-embed-text / bge-m3 ●AnythingLLM 参考教程&#xff1a; Deepseek R1打造本地化RAG知识库:安装部署使用详细教程 手把手教你&#xff1a;deepseek R1基于 AnythingLLM API 调用本地…