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

Web Snapshot 网页截图 模块代码详解

在这里插入图片描述

本文将详细解析 Web Snapshot 模块的实现原理和关键代码。这个模块主要用于捕获网页完整截图,特别优化了对动态加载内容的处理。

1. 模块概述

snapshot.py 是一个功能完整的网页截图工具,它使用 Selenium 和 Chrome WebDriver 来模拟真实浏览器行为,确保能够捕获到动态加载的内容。

1.1 核心依赖

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, StaleElementReferenceException

这些依赖提供了与浏览器交互的核心功能。

2. 类设计

2.1 初始化

def __init__(self, output_dir='snapshotFile', log_level='INFO', wait_time=None):self.output_dir = output_dirself.wait_time = wait_timeself.setup_logging(log_level)self.setup_driver()

构造函数设计考虑了三个关键参数:

  • output_dir: 输出目录
  • log_level: 日志级别
  • wait_time: 可选的等待时间

2.2 浏览器配置

def setup_driver(self):chrome_options = Options()chrome_options.add_argument('--headless')  # 无界面模式chrome_options.add_argument('--start-maximized')chrome_options.add_argument('--disable-gpu')chrome_options.add_argument('--no-sandbox')chrome_options.add_argument('--disable-dev-shm-usage')chrome_options.add_argument('--page-load-strategy=normal')self.driver = webdriver.Chrome(options=chrome_options)self.driver.set_window_size(1920, 1080)

这部分代码配置了 Chrome 浏览器的运行环境,特别注意:

  • 使用无界面模式提高性能
  • 设置合适的窗口大小
  • 配置页面加载策略

3. 智能等待机制

3.1 渐进式滚动

def scroll_to_bottom(self):self.logger.info("Starting progressive scroll to trigger lazy loading...")last_height = self.driver.execute_script("return document.body.scrollHeight")while True:# 渐进式滚动for i in range(1, 10):self.driver.execute_script(f"window.scrollTo(0, document.body.scrollHeight * {i/10});")time.sleep(0.5)# 检查是否到达底部new_height = self.driver.execute_script("return document.body.scrollHeight")if new_height == last_height:breaklast_height = new_height

这个方法通过渐进式滚动来触发懒加载内容:

  • 分10次渐进滚动到底部
  • 每次滚动后短暂等待
  • 检测页面高度变化

3.2 内容稳定性检测

def wait_for_content_stable(self, timeout=10):self.logger.info("Waiting for content to stabilize...")start_time = time.time()last_height = 0while time.time() - start_time < timeout:current_height = self.driver.execute_script("return document.body.scrollHeight")if current_height == last_height:time.sleep(2)return Truelast_height = current_heighttime.sleep(1)return False

通过监控页面高度变化来判断内容是否稳定:

  • 设置超时机制
  • 持续检测高度变化
  • 确认稳定后额外等待

3.3 动态内容检测

def wait_for_dynamic_content(self):try:# 检查 AJAX 请求script = """return (window.jQuery != null && jQuery.active == 0) || (typeof fetch === 'function' && performance.getEntriesByType('resource').length > 0);"""WebDriverWait(self.driver, 5).until(lambda driver: driver.execute_script(script))# 监控 DOM 变化script = """let observer;let changes = 0;let resolve;const promise = new Promise(r => resolve = r);observer = new MutationObserver(() => {changes++;});observer.observe(document.body, {childList: true,subtree: true,attributes: true});setTimeout(() => {observer.disconnect();resolve(changes);}, 1000);return promise;"""changes = self.driver.execute_script(script)return changes == 0except Exception as e:self.logger.debug(f"Error checking dynamic content: {str(e)}")return False

这个方法综合使用多种技术来检测动态内容:

  • 检查 AJAX 请求状态
  • 使用 MutationObserver 监控 DOM 变化
  • 设置观察超时时间

4. 截图核心流程

def capture_screenshot(self, url):try:self.driver.get(url)# 1. 等待基本加载WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((By.TAG_NAME, 'body')))# 2. 触发懒加载self.scroll_to_bottom()# 3. 等待内容稳定content_stable = self.wait_for_content_stable()# 4. 等待图片加载self.wait_for_images()# 5. 检查动态内容dynamic_content_loaded = self.wait_for_dynamic_content()# 6. 智能等待if self.wait_time is not None or not (content_stable and dynamic_content_loaded):wait_time = self.wait_time if self.wait_time is not None else 3time.sleep(wait_time)# 7. 设置最终尺寸total_height = self.driver.execute_script("""return Math.max(document.body.scrollHeight,document.body.offsetHeight,document.documentElement.clientHeight,document.documentElement.scrollHeight,document.documentElement.offsetHeight);""")viewport_width = self.driver.execute_script("""return Math.max(document.body.scrollWidth,document.body.offsetWidth,document.documentElement.clientWidth,document.documentElement.scrollWidth,document.documentElement.offsetWidth);""")# 8. 捕获截图self.driver.set_window_size(viewport_width + 100, total_height + 100)screenshot_path = os.path.join(self.output_dir, f"snapshot_{timestamp}.png")self.driver.save_screenshot(screenshot_path)return screenshot_path, json_pathexcept Exception as e:self.logger.error(f"Error capturing screenshot: {str(e)}")return None

截图过程包含多个关键步骤:

  1. 页面基本加载
  2. 触发懒加载内容
  3. 等待内容稳定
  4. 确保图片加载完成
  5. 检查动态内容
  6. 智能等待策略
  7. 计算最终页面尺寸
  8. 生成截图和元数据

5. 错误处理

模块实现了完整的错误处理机制:

  • 使用 try-except 捕获所有可能的异常
  • 详细的日志记录
  • 优雅的资源清理
  • 合适的返回值处理

6. 使用建议

6.1 基本使用

snapshot = WebSnapshot()
result = snapshot.capture_screenshot('https://example.com')

6.2 高级配置

snapshot = WebSnapshot(output_dir='custom_dir',log_level='DEBUG',wait_time=10  # 特殊情况下使用
)

6.3 错误处理

try:result = snapshot.capture_screenshot(url)if result:screenshot_path, json_path = resultprint(f"成功:{screenshot_path}")else:print("截图失败")
finally:snapshot.close()

总结

Web Snapshot 模块通过综合运用多种技术,实现了可靠的网页截图功能:

  • 智能等待机制确保内容完整性
  • 渐进式滚动触发懒加载
  • 多重检测保证动态内容加载
  • 完善的错误处理和日志记录
  • 灵活的配置选项

这些特性使得该模块能够处理各种复杂的网页场景,特别是对于包含大量动态加载内容的现代网页。
代码地址 :https://github.com/bestcarly/web-snapshot

相关文章:

Web Snapshot 网页截图 模块代码详解

本文将详细解析 Web Snapshot 模块的实现原理和关键代码。这个模块主要用于捕获网页完整截图&#xff0c;特别优化了对动态加载内容的处理。 1. 模块概述 snapshot.py 是一个功能完整的网页截图工具&#xff0c;它使用 Selenium 和 Chrome WebDriver 来模拟真实浏览器行为&am…...

Java TCP 通信:实现简单的 Echo 服务器与客户端

TCP&#xff08;Transmission Control Protocol&#xff09;是一种面向连接的、可靠的传输层协议。与 UDP 不同&#xff0c;TCP 保证了数据的顺序、可靠性和完整性&#xff0c;适用于需要可靠传输的应用场景&#xff0c;如文件传输、网页浏览等。本文将基于 Java 实现一个简单的…...

Windows 10 下 SIBR Core (i.e. 3DGS SIBR Viewers) 的编译

本文针对在 Windows 10 上从源码编译安装3DGS &#xff08;3D Gaussian Splatting&#xff09;的Viewers 即SIBR Core及外部依赖库extlibs&#xff08;预编译的版本直接在页面https://sibr.gitlabpages.inria.fr/download.html下载&#xff09; &#xff0c;参考SIBR 的官方网站…...

JavaWeb-HttpServletRequest请求域接口

文章目录 HttpServletRequest请求域接口HttpServletRequest请求域接口简介关于请求域和应用域的区别 请求域接口中的相关方法获取前端请求参数(getParameter系列方法)存储请求域名参数(Attribute系列方法)获取客户端的相关地址信息获取项目的根路径 关于转发和重定向的细致剖析…...

【C++】switch 语句编译报错:error: jump to case label

/home/share/mcrockit_3588/prj_linux/../source/rkvpss.cpp: In member function ‘virtual u32 CRkVpss::Control(u32, void*, u32)’: /home/share/mcrockit_3588/prj_linux/../source/rkvpss.cpp:242:8: error: jump to case label242 | case emRkComCmd_DBG_SaveInput:|…...

防火墙虚拟系统实验

拓扑图 需求一 安全策略要求&#xff1a; 1、只存在一个公网IP地址&#xff0c;公司内网所有部门都需要借用同一个接口访问外网 2、财务部禁止访问Internet&#xff0c;研发部门只有部分员工可以访问Internet&#xff0c;行政部门全部可以访问互联网 3、为三个部门的虚拟系统分…...

点云滤波方法:特点、作用及使用场景

点云滤波是点云数据预处理的重要步骤&#xff0c;目的是去除噪声点、离群点等异常数据&#xff0c;平滑点云或提取特定频段特征&#xff0c;为后续的特征提取、配准、曲面重建、可视化等高阶应用打下良好基础。以下是点云中几种常见滤波方法的特点、作用及使用场景&#xff1a;…...

Gradle 配置 Lombok 项目并发布到私有 Maven 仓库的完整指南

Gradle 配置 Lombok 项目并发布到私有 Maven 仓库的完整指南 在 Java 项目开发中&#xff0c;使用 Lombok 可以极大地减少样板代码&#xff08;如 getter/setter 方法、构造器等&#xff09;&#xff0c;提高开发效率。然而&#xff0c;当使用 Gradle 构建工具并将项目发布到私…...

ArcGIS Pro 基于基站数据生成基站扇区地图

在当今数字化的时代&#xff0c;地理信息系统&#xff08;GIS&#xff09;在各个领域都发挥着至关重要的作用。 ArcGIS Pro作为一款功能强大的GIS软件&#xff0c;为用户提供了丰富的工具和功能&#xff0c;使得数据处理、地图制作和空间分析变得更加高效和便捷。 本文将为您…...

【Python · Pytorch】Conda介绍 DGL-cuda安装

本文仅涉及DGL库介绍与cuda配置&#xff0c;不包含神经网络及其训练测试。 起因&#xff1a;博主电脑安装了 CUDA 12.4 版本&#xff0c;但DGL疑似没有版本支持该CUDA版本。随即想到可利用Conda创建CUDA12.1版本的虚拟环境。 1. Conda环境 1.1 Conda环境简介 Conda&#xff1…...

Spring AI:开启Java开发的智能新时代

目录 一、引言二、什么是 Spring AI2.1 Spring AI 的背景2.2 Spring AI 的目标 三、Spring AI 的核心组件3.1 数据处理3.2 模型训练3.3 模型部署3.4 模型监控 四、Spring AI 的核心功能4.1 支持的模型提供商与类型4.2 便携 API 与同步、流式 API 选项4.3 将 AI 模型输出映射到 …...

leetcode:2965. 找出缺失和重复的数字(python3解法)

难度&#xff1a;简单 给你一个下标从 0 开始的二维整数矩阵 grid&#xff0c;大小为 n * n &#xff0c;其中的值在 [1, n2] 范围内。除了 a 出现 两次&#xff0c;b 缺失 之外&#xff0c;每个整数都 恰好出现一次 。 任务是找出重复的数字a 和缺失的数字 b 。 返回一个下标从…...

Android U 分屏——SystemUI侧处理

WMShell相关的dump命令 手机分屏启动应用后运行命令&#xff1a;adb shell dumpsys activity service SystemUIService WMShell 我们可以找到其中分屏的部分&#xff0c;如下图所示&#xff1a; 分屏的组成 简图 分屏是由上分屏(SideStage)、下分屏(MainStage)以及分割线组…...

面试基础---MySQL 事务隔离级别与 MVCC 深度解析

MySQL 事务隔离级别与 MVCC 深度解析&#xff1a;原理、实践与源码分析 引言 在高并发的互联网应用中&#xff0c;数据库事务的隔离级别是保证数据一致性和并发性能的关键。MySQL 通过多版本并发控制&#xff08;MVCC&#xff09;机制实现了不同的事务隔离级别。本文将深入探…...

第十二届蓝桥杯大学A组java省赛答案整理

货物摆放 题目描述 小蓝有一个超大的仓库&#xff0c;可以摆放很多货物。 现在&#xff0c;小蓝有 nn 箱货物要摆放在仓库&#xff0c;每箱货物都是规则的正方体。小蓝规定了长、宽、高三个互相垂直的方向&#xff0c;每箱货物的边都必须严格平行于长、宽、高。 小蓝希望所…...

浅浅初识AI、AI大模型、AGI

前记&#xff1a;这里只是简单了解&#xff0c;后面有时间会专门来扩展和深入。 当前&#xff0c;人工智能&#xff08;AI&#xff09;及其细分领域&#xff08;如AI算法工程师、自然语言处理NLP、通用人工智能AGI&#xff09;的就业前景呈现高速增长态势&#xff0c;市场需求…...

flink集成tidb cdc

Flink TiDB CDC 详解 1. TiDB CDC 简介 1.1 TiDB CDC 的核心概念 TiDB CDC 是 TiDB 提供的变更数据捕获工具&#xff0c;能够实时捕获 TiDB 集群中的数据变更&#xff08;如 INSERT、UPDATE、DELETE 操作&#xff09;&#xff0c;并将这些变更以事件流的形式输出。TiDB CDC 的…...

【flutter】TextField输入框工具栏文本为英文解决(不用安装插件版本

输入框长按选项菜单复制、粘贴、剪切、全选部分默认为英文&#xff0c;对于只需要对此部分做中文本地化&#xff0c;不需要考虑其他语言及全局本地化的项目&#xff0c;可以直接自定义一个本地化代理方法进行覆盖&#xff0c;不需要额外下载插件 // 自定义本地化代理 class _C…...

推荐1款OCR的扫描仪软件,无需安装,打开即用!

聊一聊 现在日常办公&#xff0c;很多时候还是需要扫描仪配合。 很多时候需要将文件搜索成PDF再传输。 今天给大家分享一款OCR扫描仪软件。 软件介绍 OCR的扫描仪软件 支持扫描仪共享。 支持WIA、TWAIN、SANE和ESCL驱动程序。 还可以批量多扫描仪配置扫描&#xff0c;支持…...

SpringBoot为什么默认使用CGLIB?

大家好&#xff0c;我是锋哥。今天分享关于【SpringBoot为什么默认使用CGLIB?】面试题。希望对大家有帮助&#xff1b; SpringBoot为什么默认使用CGLIB? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Spring Boot 默认使用 CGLIB&#xff08;Code Generation Li…...

去除HTML有序列表(ol)编号的多种解决方案

以下是去除HTML有序列表(ol)编号的多种解决方案&#xff1a; <!DOCTYPE html> <html> <head> <style> /* 基础方案&#xff1a;完全移除编号 */ ol.no-number {list-style-type: none; /* 移除默认编号 */padding-left: 0; /* 移除默认缩进 */…...

神经网络|(十三)|SOM神经网络

【1】引言 前序已经对神经网络有了基础认识&#xff0c;今天先学习SOM神经网络。 前序学习文章链接包括且不限于&#xff1a; 神经网络|(十一)|神经元和神经网络-CSDN博客 神经网络|(十二)|常见激活函数-CSDN博客 【2】SOM神经网络 SOM神经网络是一种结构比较简单、但是理…...

IP协议、DNS协议、DHCP协议、Telent协议的记忆总结

首先记忆一下几个协议的端口号 HTTP&#xff1a;超文本传输协议 80 HTTPS&#xff1a;安全传输协议 443 DHCP&#xff1a;动态主机配置协议 67/68 DNS&#xff1a;域名解析协议 53 FTP&#xff1a;文件传输协议 20/21 TFTP&#xff1a;简单文件传输协议 69 TELENT&#xff1a;远…...

Pico 4 Enterprise(企业版)与Unity的交互-有线串流调试篇

入手了Pico 4 E做VR开发&#xff0c;谁知入了天坑...根据官方文档&#xff0c;尝试了串流助手、企业串流、PICO Developer Center&#xff0c;陷入了各种版本问题、环境问题的陷阱。而且Pico4E的OS自24年12开始就不再更新&#xff0c;头盔中预装的企业串流版本也较低&#xff0…...

DeepSeek-R1:使用KTransformers实现高效部署指南

KTransformers作为一个开源框架&#xff0c;专门为优化大规模语言模型的推理过程而设计。它支持GPU/CPU异构计算&#xff0c;并针对MoE架构的稀疏性进行了特别优化&#xff0c;可以有效降低硬件要求&#xff0c;允许用户在有限的资源下运行像DeepSeek-R1这样庞大的模型。 硬件…...

企业日常工作中常用的 Linux 操作系统命令整理

Linux 操作系统命令整理 在企业级运维、开发和日常工作中&#xff0c;Linux 命令是绕不开的核心技能。不论是日志排查、进程管理&#xff0c;还是高效运维优化&#xff0c;掌握这些命令都能让你事半功倍&#xff01;本篇文章整理了自己在日常工作中积累最常用的 Linux 命令&am…...

任务9:交换机基础及配置

CSDN 原创主页&#xff1a;不羁https://blog.csdn.net/2303_76492156?typeblog 一、交换机基础 交换机的概念&#xff1a;交换机是一种网络设备&#xff0c;用于连接多台计算机或网络设备&#xff0c;实现数据包在局域网内的快速交换。交换机基于MAC地址来转发数据包&#x…...

Notepad++ 8.6.7 安装与配置全攻略(Windows平台)

一、软件定位与核心优势 Notepad 是开源免费的代码/文本编辑器&#xff0c;支持超过80种编程语言的高亮显示&#xff0c;相比系统自带记事本具有以下优势&#xff1a; 轻量高效&#xff1a;启动速度比同类软件快30%插件扩展&#xff1a;支持NppExec、JSON Viewer等200插件跨文…...

SpringMVC请求处理流程:DispatcherServlet工作原理

文章目录 引言一、DispatcherServlet概述二、DispatcherServlet初始化过程三、请求接收与处理器匹配四、请求参数绑定与处理器执行五、视图解析与渲染六、异常处理机制总结 引言 SpringMVC框架是Java Web开发中最流行的MVC框架之一&#xff0c;其核心组件DispatcherServlet作为…...

YOLOv8目标检测推理流程及C++代码

这部分主要是使用c++对Onnx模型进行推理,边先贴代码,过段时间再详细补充下代码说明。 代码主要分成三部分,1.main_det.cpp推理函数主入口;2.inference_det.h 头文件及inference_det.cpp具体函数实现;3.CMakeList.txt. 1.main_det 推理配置信息全部写在config.txt中,执行…...