一文掌握Splash的详细使用

发布于:2025-02-26 ⋅ 阅读:(11) ⋅ 点赞:(0)

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 来处理动态网页抓取任务了。