文章目录
- 1. 安装与启动 Splash
- 1.1 使用 Docker 安装
- 1.2 直接安装
- 2. 基本用法
- 2.1 访问 Splash 界面
- 2.2 使用 Splash 渲染页面
- 2.3 使用 Lua 脚本
- 3. 高级用法
- 3.1 处理 JavaScript
- 3.2 截图与 PDF
- 3.3 处理 AJAX 请求
- 3.4 设置请求头
- 3.5 处理 Cookies
- 4. 与 Scrapy 集成
- 4.1 安装 Scrapy-Splash
- 4.2 配置 Scrapy
- 4.3 使用 SplashRequest
- 5. 常见问题与解决方案
- 5.1 页面加载不完全
- 5.2 内存不足
- 6. 总结
Splash 是一个基于 JavaScript 的渲染服务,主要用于抓取动态网页内容。它能够执行 JavaScript 代码并返回渲染后的 HTML 内容,适用于需要处理动态加载内容的爬虫场景。以下是 Splash 的详细使用指南:
官方文档:https://splash.readthedocs.io/en/stable/
1. 安装与启动 Splash
1.1 使用 Docker 安装
Splash 推荐通过 Docker 安装和运行。
docker pull scrapinghub/splash
docker run -p 8050:8050 scrapinghub/splash
启动后,Splash 服务会运行在 http://localhost:8050。
1.2 直接安装
如果你不想使用 Docker,可以直接安装 Splash:pip install scrapy-splash
,然后启动 Splash 服务:
splash
2. 基本用法
2.1 访问 Splash 界面
在浏览器中访问 http://localhost:8050
,可以看到 Splash 的 Web 界面。在这里,可以输入 URL 并查看渲染结果。
2.2 使用 Splash 渲染页面
通过 HTTP API 调用 Splash 渲染页面。以下是一个简单的示例:
curl 'http://localhost:8050/render.html?url=https://example.com&wait=2'
参数说明:
- url: 需要渲染的页面 URL。
- wait: 等待时间(秒),用于等待页面加载完成。
2.3 使用 Lua 脚本
Splash 支持通过 Lua 脚本自定义渲染逻辑。以下是一个简单的 Lua 脚本示例:
function main(splash)
splash:go("https://example.com")
splash:wait(2)
return splash:html()
end
通过 HTTP API 调用该脚本:
curl -X POST 'http://localhost:8050/execute' --data '{
"lua_source": "function main(splash) splash:go(\"https://example.com\") splash:wait(2) return splash:html() end"
}'
3. 高级用法
3.1 处理 JavaScript
Splash 可以执行 JavaScript 代码并返回结果。以下是一个示例:
# 样例1
function main(splash)
splash:go("https://example.com")
splash:wait(2)
local title = splash:evaljs("document.title")
return title
end
# 样例2
function main(splash)
splash:go("https://example.com")
splash:wait(0.5)
splash:runjs("document.title = 'New Title';")
return splash:html()
end
3.2 截图与 PDF
Splash 支持截取页面截图和生成 PDF 文件。
截图:
function main(splash)
splash:go("https://example.com")
splash:wait(2)
return splash:png()
end
通过 HTTP API 请求截图:
curl -X POST 'http://localhost:8050/execute' --data '{
"lua_source": "function main(splash) splash:go(\"https://example.com\") splash:wait(0.5) return splash:png() end"
}' --output screenshot.png
生成 PDF:
function main(splash)
splash:go("https://example.com")
splash:wait(2)
return splash:pdf()
end
3.3 处理 AJAX 请求
Splash 可以等待 AJAX 请求完成后再返回结果。
function main(splash)
splash:go("https://example.com")
splash:wait_for_resume('
function() {
setTimeout(function() {
document.title = "New Title";
splash.resume();
}, 2000);
}
')
return splash:html()
end
3.4 设置请求头
可以通过 Lua 脚本设置请求头:
function main(splash)
splash:set_user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
splash:go("https://example.com")
splash:wait(2)
return splash:html()
end
3.5 处理 Cookies
Splash 支持设置和获取 Cookies。
设置 Cookies:
# 样例1
function main(splash)
splash:init_cookies({
{ name = "test", value = "123", domain = "example.com" }
})
splash:go("https://example.com")
splash:wait(2)
return splash:html()
end
# 样例2
function main(splash)
splash:go("https://example.com")
splash:wait(0.5)
splash:set_cookie("name", "value", "/", "example.com")
return splash:html()
end
获取 Cookies:
function main(splash)
splash:go("https://example.com")
splash:wait(2)
local cookies = splash:get_cookies()
return cookies
end
4. 与 Scrapy 集成
Scrapy 是一个强大的 Python 爬虫框架,可以通过 scrapy-splash
插件与 Splash 集成。
4.1 安装 Scrapy-Splash
pip install scrapy scrapy-splash
4.2 配置 Scrapy
在 settings.py 中添加以下配置:
SPLASH_URL = 'http://localhost:8050'
DOWNLOADER_MIDDLEWARES = {
'scrapy_splash.SplashCookiesMiddleware': 723,
'scrapy_splash.SplashMiddleware': 725,
'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
}
SPIDER_MIDDLEWARES = {
'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,
}
DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'
HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'
4.3 使用 SplashRequest
在 Scrapy 爬虫中使用 SplashRequest 渲染页面:
import scrapy
from scrapy_splash import SplashRequest
class MySpider(scrapy.Spider):
name = 'example'
start_urls = ['https://example.com']
def start_requests(self):
for url in self.start_urls:
yield SplashRequest(url, self.parse, args={'wait': 2})
def parse(self, response):
title = response.css('title::text').get()
yield {'title': title}
5. 常见问题与解决方案
5.1 页面加载不完全
原因: 页面内容可能通过 AJAX 动态加载。
解决方案: 增加 wait 参数,或使用 Lua 脚本等待特定元素出现。
5.2 内存不足
原因: 渲染大量页面可能导致内存不足。
解决方案: 增加 Docker 容器的内存限制,或优化 Lua 脚本减少内存使用。
6. 总结
Splash 是一个强大的工具,专为网页抓取和 JavaScript 渲染设计。通过本文的介绍,你应该已经掌握了 Splash 的基本用法和一些高级技巧。现在,你可以开始使用 Splash 来处理动态网页抓取任务了。