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

解锁豆瓣高清海报(三)从深度爬虫到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 分半钟).
  • 性能对比: 对比了 V1 和 V2 版本的性能, 验证了 V2 版本 (构造 URL) 的速度优势.

相关文章:

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

脚本地址: 项目地址: Gazer PosterBandit_v2.py 前瞻 之前的 PosterBandit.py 是按照深度爬虫的思路一步步进入海报界面来爬取, 是个值得学习的思路, 但缺点是它爬取慢, 仍然容易碰到豆瓣的 418 错误, 本文也会指出彻底解决旧版 418 错误的方法并提高爬取速度. 现在我将介绍…...

IDEA单元测试插件 SquareTest 延长试用期权限

SquareTest是一款强大的IDEA单元测试生成插件工具&#xff0c;具体使用方法就不过多介绍了&#xff0c;这里主要介绍变更试用期&#xff0c;方便大家使用 配置信息 我的电脑安装前提配置条件 IntelliJ IDEA 2023.2windows 系统 软件安装 IntelliJ IDEA 直接安装插件Squar…...

PLC的五个学习步骤

五个学习步骤详解&#xff1a; 1. 夯实电气基础 (第一步) 核心思想: PLC控制技术是建立在传统电气控制技术之上的&#xff0c;因此扎实的电气基础至关重要。学习内容: 电气元件原理: 深入理解继电器、接触器、按钮、三相异步电机等常用电气元件的工作原理。这是理解电气控制回…...

深度学习05 ResNet残差网络

目录 传统卷积神经网络存在的问题 如何解决 批量归一化BatchNormalization, BN 残差连接方式 ​残差结构 ResNet网络 ResNet 网络是在 2015年 由微软实验室中的何凯明等几位大神提出&#xff0c;斩获当年ImageNet竞赛中分类任务第一名&#xff0c;目标检测第一名。获得CO…...

卷积神经网络CNN

目录 一、CNN概述 二、图像基础知识 三、卷积层 3.1 卷积的计算 3.2 Padding 3.3 Stride 3.4 多通道卷积计算 3.5 多卷积核卷积计算 3.6 特征图大小计算 3.7 Pytorch 卷积层API 四、池化层 4.1 池化计算 4.2 Stride 4.3 Padding 4.4 多通道池化计算 4.5 Pytorc…...

Android:播放Rtsp视频流的两种方式

一.SurfaceView Mediaplayer XML中添加SurfaceView: <SurfaceViewandroid:id"id/surface_view"android:layout_width"match_parent"android:layout_height"match_parent"/> Activity代码&#xff1a; package com.android.rtsp;impor…...

web信息泄露 ctfshow-web入门web1-web10

01做题思路 判断做题的思路是读取&#xff0c;写入&#xff0c;还是执行判断大概的类型&#xff0c;有登录逻辑就尝试sql注入&#xff0c;有下载逻辑就尝试文件读取&#xff0c;有源码就做源码审计 02信息泄露及利用 robots.txt 以ctfshow的web1为例&#xff0c;访问robots…...

Log4j在Spring项目中的应用与实践

在现代Java开发中&#xff0c;日志记录是不可或缺的一部分。它不仅帮助开发者调试和监控应用程序的运行状态&#xff0c;还能在出现问题时快速定位原因。今天&#xff0c;我们就来探讨如何在Spring项目中使用Log4j进行日志管理&#xff0c;并通过具体的实例来展示其强大的功能。…...

docker安装mysql:8.0

1.docker源 目前docker国内的源基本上用不了了&#xff0c;建议去淘宝找一找&#xff0c;我整了一个大概是10R一个月。 2.拉取镜像 docker pull mysql:8.0 3.启动容器 命令如下&#xff1a; docker run \-p 3306:3306 \-e MYSQL_ROOT_PASSWORD123456 \-v /home/data/mysq…...

搭建一个 Spring Boot 项目,解决jdk与springboot版本不匹配

搭建一个 Spring Boot 项目 方式一&#xff1a;使用 Spring Initializr Spring Initializr 是一个基于 Web 的工具&#xff0c;用于快速生成 Spring Boot 项目的基础结构。 访问 Spring Initializr 网站&#xff1a;https://start.spring.io/配置项目信息&#xff1a; …...

心心相系:十颗心

心心相系&#xff1a;十颗心 【1】心脏&#xff1b;人心&#xff0c;热心 heart //注&#xff1a;h-通c-或k- warmhearted a.热心的&#xff0c;热心肠的&#xff1b;亲切的a warm-hearted person 为人古道热肠 词根cardi(o)-(heart)&#xff0c;例词&#xff1a;cardiology(…...

ChatGPT行业热门应用提示词案例-AI绘画类

AI 绘画指令是一段用于指导 AI 绘画工具&#xff08;如 DALLE、Midjourney 等&#xff09;生成特定图像的文本描述。它通常包含场景、主体、风格、色彩、氛围等关键信息&#xff0c;帮助 AI 理解创作者的意图&#xff0c;从而生成符合要求的绘画作品。 ChatGPT 拥有海量的知识…...

前端面试手写--虚拟列表

目录 一.问题背景 二.代码讲解 三.代码改装 四.代码发布 今天我们来学习如何手写一个虚拟列表,本文将把虚拟列表进行拆分并讲解,然后发布到npm网站上. 一.问题背景 为什么需要虚拟列表呢?这是因为在面对大量数据的时候,我们的浏览器会将所有数据都渲染到表格上面,但是渲…...

达梦数据库针对慢SQL,收集统计信息清除执行计划缓存

前言&#xff1a;若遇到以下场景&#xff0c;大概率是SQL走错了执行计划&#xff1a; 1、一条SQL在页面上查询特别慢&#xff0c;但拿到数据库终端执行特别快 2、一条SQL在某种检索条件下查询特别慢&#xff0c;但拿到数据库终端执行特别快 此时&#xff0c;可以尝试按照下述步…...

李沐--动手学深度学习 序列模型

1.使用正弦函数和可加性噪声生成序列数据 import torch from torch import nn from d2l import torch as d2l#使用正弦函数和可加性噪声生成序列数据 T 1000 #总共产生1000个点 time torch.arange(1,T1,dtypetorch.float32) x torch.sin(0.01*time) torch.normal(0,0.2,(…...

数据分析、商业智能、业务分析三者之间的关系

商业智能 (Business Intelligence, BI)、业务分析 (Business Analytics, BA) 和数据分析 (Data Analytics, DA) 三者都与数据密切相关&#xff0c;但在目标、方法和应用上存在差异。为了能够清晰地解释&#xff0c;下面将从定义入手&#xff0c;然后阐述它们之间的联系和区别。…...

【Spring+MyBatis】留言墙的实现

目录 1. 添加依赖 2. 配置数据库 2.1 创建数据库与数据表 2.2 创建与数据库对应的实体类 3. 后端代码 3.1 目录结构 3.2 MessageController类 3.3 MessageService类 3.4 MessageMapper接口 4. 前端代码 5. 单元测试 5.1 后端接口测试 5.2 使用前端页面测试 在Spri…...

让编程变成一种享受-明基RD320U显示器

引言 作为一名有着多年JAVA开发经验的从业者&#xff0c;在工作过程中&#xff0c;显示器的重要性不言而喻。它不仅是我们与代码交互的窗口&#xff0c;更是影响工作效率和体验的关键因素。在多年的编程生涯中&#xff0c;我遇到过各种各样的问题。比如&#xff0c;在进行代码…...

【嵌入式Linux应用开发基础】fork()函数

目录 一、fork 函数概述 1.1. 函数作用 1.2. 函数原型与头文件 1.3. 返回值 1.4. 核心特性 二、父子进程的区别与联系 2.1. 相同点 2.2. 不同点 三、典型应用场景 3.1. 多任务处理 3.2. 守护进程创建 3.3. 执行外部程序 3.4. 并行计算 四、fork 函数的关键注意事…...

2024 年 CSDN 博客之星年度评选:技术创作与影响力的碰撞(统计时间2025-02-17 11:06:06)

摘要&#xff1a;在技术的海洋里&#xff0c;每一位博主都像是一座独特的灯塔&#xff0c;用自己创作的光芒照亮他人前行的道路。2024 年 CSDN 博客之星年度评选活动&#xff0c;正是对这些灯塔的一次盛大检阅&#xff0c;让我们看到了众多优秀博主在技术创作领域的卓越表现以及…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...