Python爬虫第18节-动态渲染页面抓取之Splash使用上篇
目录
引言
一、Splash 的简介与安装
1.1 简介
1.2 安装
二、Splash 的使用
三、Splash Lua 脚本开发
3.1 脚本入口与返回值
3.2 异步处理
四、Splash 对象属性
4.1 `args`
4.2 `js_enabled`
4.3 `resource_timeout`
4.4 `images_enabled`
4.5 `scroll_position`
4.6 `plugins_enabled`
五、Splash 对象方法
5.1 `go`:加载页面
5.2 `wait`:等待延时
5.3 `evaljs`:执行 JavaScript 并返回结果
5.4 `runjs`:执行 JavaScript 语句
5.5 `autoload`:预加载 JavaScript 库
5.6 `http_get`/`http_post`:模拟 HTTP 请求
六、总结与后续
引言
在动态网页抓取场景中,Splash 作为一款轻量级 JavaScript 渲染服务,为解决页面动态加载内容的获取难题提供了高效方案。它通过集成浏览器内核与 HTTP API,结合 Lua 脚本灵活控制渲染流程,可实现页面源码提取、截图生成、性能分析等功能。本文将围绕 Splash 的核心功能、使用流程及脚本开发要点展开介绍,帮助读者快速掌握这一动态渲染抓取工具的实践方法。
一、Splash 的简介与安装
1.1 简介
Splash 是个 JavaScript 渲染服务,它相当于一个带有 HTTP API 的轻量级浏览器,并且和 Python 里的 Twisted、QT 库进行了对接。借助它,我们也能够实现对动态渲染页面的抓取。
使用 Splash 能够实现下面这些功能:
- 用异步的方式处理多个网页的渲染过程
- 获取渲染后页面的源代码或者截图
- 通过关闭图片渲染或者使用 Adblock 规则来加快页面的渲染速度
- 可以执行特定的 JavaScript 脚本
- 能够通过 Lua 脚本来控制页面的渲染过程
- 获取渲染的详细过程,并且以 HAR(HTTP Archive)格式呈现出来
下面我们来看看它的具体使用方法。在开始使用之前,要保证已经正确安装了 Splash 并且服务能正常运行。要是没安装的话,可以自己在网上搜索安装方法。
Splash 与 Selenium 对比
1.2 安装
Splash 安装步骤(Windows 系统)
(1)安装 Docker Desktop
1. 系统要求
- 操作系统:
- Windows 11 64 位(版本 22H2 或更高,支持 Home/Pro/Enterprise/Education)。
- Windows 10 64 位(版本 22H2 (build 19045) 或更高,仅 Pro/Enterprise/Education 支持 Windows 容器)。
- 硬件:64 位处理器(支持 SLAT)、4GB 内存、启用 BIOS/UEFI 硬件虚拟化。
2. 安装方式
- 交互式安装:
1. 从 [Docker Desktop 官网](https://hub.docker.com/editions/community/docker-ce-desktop-windows) 下载安装程序。
2. 双击运行 `Docker Desktop Installer.exe`,按向导完成安装,默认安装路径为 `C:\Program Files\Docker\Docker`。
3. 安装完成后,手动启动 Docker Desktop 并接受服务协议。
- 命令行安装:
# PowerShell 示例
Start-Process 'Docker Desktop Installer.exe' -Wait -ArgumentList 'install', '--accept-license'
3. 启用 WSL 2 或 Hyper-V
- 在安装向导中选择后端(WSL 2 或 Hyper-V),系统自动适配仅支持的选项。
(2)安装 Splash 服务
1. 拉取 Splash 镜像
需要翻墙网络
docker pull scrapinghub/splash
2. 运行 Splash 容器
docker run -d -p 8050:8050 scrapinghub/splash
- `-d`:后台运行容器。
- `-p 8050:8050`:将容器端口 8050 映射到本地 8050 端口。
3. 验证安装
访问 `http://localhost:8050`,若看到 Splash 管理界面,则安装成功。
(3)安装 Scrapy-Splash 插件
pip install scrapy-splash
Splash 核心优势
- 异步处理:支持同时渲染多个页面,提升抓取效率。
- 轻量级架构:基于 Docker 容器化部署,资源占用少,适合分布式部署。
- 脚本灵活性:通过 Lua 直接控制浏览器行为,支持执行 JS、设置请求头、模拟滚动等操作。
- 性能优化:可禁用图片、插件或设置超时,减少资源消耗,加速渲染。
api 文档:
Splash HTTP API — Splash 3.5 documentation
二、Splash 的使用
Splash 是一个基于 JavaScript 渲染的服务,本质是带有 HTTP API 的轻量级浏览器,集成了 Python 的 Twisted 和 QT 库,可实现动态网页渲染与抓取。
(1)功能特性
Splash 支持以下核心功能:
- 异步处理多个网页渲染任务
- 获取渲染后的页面源码、截图或 HAR 格式的请求日志
- 通过禁用图片加载或应用 Adblock 规则加速渲染
- 执行自定义 JavaScript 脚本
- 通过 Lua 脚本控制页面渲染流程
- 输出详细的渲染过程信息
(2)环境准备
使用前需确保已正确安装 Splash 并启动服务。若未安装,可参考第 1 章指引完成部署。
(3)快速入门:Web 页面测试
启动 Splash 后,访问 `http://localhost:8050/` 进入测试界面:
1. 输入 URL:右侧输入框默认填写 `http://google.com`,修改为 `https://www.baidu.com`。
2. 触发渲染:点击按钮,Splash 会加载页面并返回:
- 页面截图
- HAR 格式的加载统计数据(包含 CSS、JavaScript 等资源的加载过程)
- 网页源代码
核心脚本示例(默认渲染逻辑):
function main(splash, args) assert(splash:go(args.url)) -- 加载页面 assert(splash:wait(0.5)) -- 等待 0.5 秒 return { html = splash:html(), -- 页面源码 png = splash:png(), -- 页面截图 har = splash:har() -- 加载过程日志 }
end
该脚本通过 Lua 语言控制渲染流程,模拟浏览器行为并输出多格式结果。
三、Splash Lua 脚本开发
3.1 脚本入口与返回值
- 入口函数:必须命名为 `main`,接收 `splash`(核心对象)和 `args`(参数)作为输入。
function main(splash, args) splash:go("http://www.baidu.com") splash:wait(0.5) local title = splash:evaljs("document.title") -- 执行 JavaScript 获取标题 return {title=title} -- 返回字典或字符串 end
- 返回值类型:
- 字典:`return {hello="world!"}`
- 字符串:`return "hello"`
3.2 异步处理
Splash 支持异步任务处理,通过循环加载多个 URL 并并行渲染:
function main(splash, args) local urls = args.urls or {"www.baidu.com", "www.taobao.com", "www.zhihu.com"} local results = {} for index, url in ipairs(urls) do local ok, reason = splash:go("http://" .. url) if ok then splash:wait(2) results[url] = splash:png() -- 保存截图 end end return results
end
注意:Lua 使用 `..` 进行字符串拼接,`ipairs` 用于遍历数组。
四、Splash 对象属性
4.1 `args`
获取脚本参数,支持两种写法:
-- 方式一:通过第二个参数直接获取
function main(splash, args) local url = args.url
end -- 方式二:通过 splash.args 获取
function main(splash) local url = splash.args.url
end
4.2 `js_enabled`
控制 JavaScript 执行(默认 `true`):
function main(splash, args)splash:go("https://www.baidu.com")splash.js_enabled = falselocal title = splash:evaljs("document.title")return {title=title}
end
注意:禁用后调用 `evaljs` 会抛出异常,通常保持默认开启。
4.3 `resource_timeout`
设置资源加载超时时间(秒),`0` 或 `nil` 表示不超时:
function main(splash)splash.resource_timeout = 0.1 -- 超时时间 0.1 秒assert(splash:go('https://www.taobao.com'))return splash:png()
end
4.4 `images_enabled`
控制图片加载(默认 `true`):
function main(splash, args)splash.images_enabled = false -- 禁用图片加载,提升速度 assert(splash:go('https://www.jd.com'))return {png=splash:png()}
end
4.5 `scroll_position`
控制页面滚动位置:
splash.scroll_position = {y=400} -- 向下滚动 400 像素
splash.scroll_position = {x=100, y=200} -- 向右滚动 100 像素,向下滚动 200 像素
示例:
function main(splash, args)assert(splash:go('https://www.taobao.com'))splash.scroll_position = {y=400}return {png=splash:png()}
end
4.6 `plugins_enabled`
此属性可以控制浏览器插件(如 Flash 插件)是否开启。默认情况下,此属性是 false,表示不开启。可以使用如下代码控制其开启和关闭:
splash.plugins_enabled = true/false
五、Splash 对象方法
5.1 `go`:加载页面
模拟 HTTP 请求(支持 GET/POST):
local ok, reason = splash:go{ url = "http://httpbin.org/post", http_method = "POST", body = "name=Germey" -- POST 表单数据(Content-Type: application/x-www-form-urlencoded)
}
5.2 `wait`:等待延时
splash:wait(2) -- 等待 2 秒
splash:wait{time=2, cancel_on_redirect=true} -- 重定向时终止等待
5.3 `evaljs`:执行 JavaScript 并返回结果
local title = splash:evaljs("document.title") -- 获取页面标题
5.4 `runjs`:执行 JavaScript 语句
splash:runjs("var foo = function() { return 'bar'; }") -- 声明 JavaScript 函数
local result = splash:evaljs("foo()") -- 调用函数
5.5 `autoload`:预加载 JavaScript 库
splash:autoload("https://code.jquery.com/jquery-2.1.3.min.js") -- 加载 jQuery
local version = splash:evaljs("$.fn.jquery") -- 获取库版本
5.6 `http_get`/`http_post`:模拟 HTTP 请求
-- GET 请求
local response = splash:http_get("http://httpbin.org/get") -- POST 请求(JSON 数据)
local response = splash:http_post{ url = "http://httpbin.org/post", body = json.encode({name="Germey"}), headers = {["content-type"]="application/json"}
}
六、总结与后续
Splash 通过 Lua 脚本提供了灵活的页面渲染控制能力,支持模拟浏览器行为、执行自定义脚本及异步任务处理。结合其 HTTP API,可高效实现动态网页的数据抓取与分析。实际使用中需注意资源加载策略、JavaScript 执行逻辑及异步任务的异常处理,以优化渲染性能与稳定性。本节Splash 对象方法还没讲完,请继续看下一节内容讲解。