Splash HTTP API 

官方文档

查阅 安装 来获取splash,并运行。

splash所有的 endpoints 通过发送GET或POST请求来访问。

大多数通用endpoints可以通过 Lua 脚本执行。

特定情况下,一些endpoints更容易被执行--例如:render.png 返回渲染后页面的屏幕截图(.png);如果你不需要和页面交互,render.json 可以返回一个包含HTML,PNG 和其他信息的json字典。

 

render.html

返回js渲染完成后的html。

参数:

  • url : string : 必须
    • 需要渲染的页面的url
  • baseurl string : 可选
    • 页面中使用相对路径引用的资源可以通过加上baseurl捕获
  • timeout float : 可选
    • 渲染页面的超时时间,单位是 s ,默认值是 30s
    • 默认可设置的最大值为 90s,可以通过下面的命令修改允许的最大值:
      $ docker run -it -p 8050:8050 scrapinghub/splash --max-timeout 300
  • resource_timeout float : 可选
    • 单独网络请求的超时时间
  • wait float : 可选
    • 默认值为 0 ,页面加载完成等待多长时间后更新,如果需要获得 setInterval/setTimeout 被调用 或者 图片渲染完成的页面,将这个值设为 大于 0 。
  • proxy string : 可选
    • 代理文件或代理URL的名字,查阅相关文档 。
    • 代理URL的格式:[protocol://][user:password@]proxyhost[:port]
    • protocol可以是:http 或 protocol
    • 如果没有设置端口,将使用默认端口:1080
  • js string 可选
  • js_source string 可选
  • filters string 可选
  • allowed_domains string 可选
    • 域名范围,有多个时,用 ',' 分隔
  • allowed_content_types string 可选
    • 允许的content-type,有多个时,用 ',' 分隔。Wildcards 支持使用 fnmatch 语法
  • forbidden_content_types string 可选
    • 禁止的content-type,有多个时,用 ',' 分隔。Wildcards 支持使用 fnmatch 语法
  • viewport string 可选
    • 选页面的浏览器的窗口大小,默认 '1024x768'。格式:“<width>x<height>”
  • images integer 可选
    • 是否下载图片,1 代表下载,0代表不下载。默认值为 0 。
    • 即使该参数的值为0,缓存的图片也有可能被展示出来。你也可以用 Request Filters 来剥离不需要的内容。
  • headers JSON array or object 可选
    • 为第一次传出的request设置请求头。
    • 该选项仅支持 ‘application/json’ 的POST 请求,值可以使 (header_name, header_value)  组成的JSON列表,也可以是  {header_name: header_value} 这样的JSON对象。
    • 与其他请求头不同,"User-Agent"用于所有传出的请求。
  • body string 可选
    • POST请求的body,默认必须的content-type为application/x-www-form-urlencoded。
  • http_method string 可选
    • Splash发送请求的请求方法,默认为GET
  • save_args JSON array or a comma-separated string 可选
    • 要缓存的参数的名称列表,return X-Splash-Saved-Arguments HTTP header with a list of SHA1 hashes for each argument (a semicolon-separated list of name=hash pairs):
      name1=9a6747fc6259aa374ab4e1bb03074b6ec672cf99;name2=ba001160ef96fe2a3f938fea9e6762e204a562b3
    • Client 可以通过参数load_args 来传递这些散列值,当参数值不经常改变时,这么做是有效的(例如:js_source  或者 lua_source
  • load_args JSON object or a string 可选
    • 加载缓存中的参数,格式:{"name": "<SHA1 hash>", ...}  或者 'name=hash'(多个时,用分号隔开)。
    • Splash尝试通过提供的 SHA1 哈希值,在缓存中获取 load_args 中标明的参数
    • 如果在缓存中没有找到该参数,Splash将返回 HTTP 498 ,这时,应该使用 save_args  缓存所有参数后,重发请求。
    • load_args 和 save_args 通过不为每个请求都发送大量的参数,来节省网络流量。当处理 js_source and lua_source 时,这是一个很好的选择。
    • Splash 通过 LRU 缓存这些值;entries 的数量会被限制,当Splash重启时,缓存将被清空;这样的缓存不是持久的。你应该随时准备重新缓存这些数据。
  • html5_media integer 可选
    • 是否启用 HTML5 media ,可选值:0(不启用)和 1(启用)。
    • 因为不稳定,目前 HTML5 media 默认被禁用。以后,Splash可能会默认启用。
    • 查阅相关文档

 

使用render.html的例子

curl 'http://localhost:8050/render.html?url=http://domain.com/page-with-javascript.html&timeout=10&wait=0.5'

 

 

render.png

返回渲染完成的屏幕截图,图片格式为.png。

参数与 render.html 相同,并新增一下参数:

  • width integer 可选
    • 在原来的长宽比下,调整屏幕截图的宽度
  • height integer 可选
    • 裁剪屏幕截图至指定高度(以像素为单位),通常与 width 一起使用,获取缩略图。
  • render_all int 可选
    • 可选值 :0 和 1,默认 0
    • 当值为1时,拓展 viewport 包含整个页面(可能非常高)。
    • 当值为1时,需要要设置 wait 大于 0。
  • scale_method string 可选
    • 可选值:raster 和 vector
    • 值为 raster 时:rescaling operation performed via width parameter is pixel-wise
    • 值为 vector 时:rescaling is done element-wise during rendering
    • Vector-based rescaling is more performant and results in crisper fonts and sharper element boundaries, however there may be rendering issues, so use it with caution.

 

使用render.html的例子

# render with timeout
curl 'http://localhost:8050/render.png?url=http://domain.com/page-with-javascript.html&timeout=10'

# 320x240 thumbnail
curl 'http://localhost:8050/render.png?url=http://domain.com/page-with-javascript.html&width=320&height=240'

 

render.jpeg

返回渲染完成的屏幕截图,图片格式为.jpeg。

参数与render.png相同,新增以下参数:

  • quality integer optional
    • jpeg 质量,范围 0 至 100,默认 75。
    • 值应该小于95, 值为100时会禁用JEPG算法的某些部分,所生成的大文件在提升图像质量上没有明显的效果。

 

使用render.jpeg的例子

# render with default quality
curl 'http://localhost:8050/render.jpeg?url=http://domain.com/'

# render with low quality
curl 'http://localhost:8050/render.jpeg?url=http://domain.com/&quality=30'

 

 

render.har

以HAR格式返回Splash与网站交互的信息,包含:request、response、timinings、header等。

可以联机 HAR viewer 来查看这些信息,这和 chrome开发者模式的 'network' 很相似。

当 ‘request_body’ and ‘response_body’  被设置为 1 时,request 内容和response 内容 将被包含。

Due to the HAR format specification lacking a method of encoding binary request data, a non-standard encoding field is included in postData,

which, similarly to the field of same name in HAR responses, has the value base64 when the request body has been encoded as such.

参数与 render.html一样,新增以下参数:

  • request_body int : 可选
    • 可选值:0和1
    • 是否包含request content
    • 默认为 0
  • response_body int 可选
    • 可选值:0和1
    • 是否包含response content
    • 默认为 0

 

render.json

返回一个JSON对象,包含页面渲染完成后的 HTML、PNG等。

参数与 render.jpeg 相同,新增以下参数:

  • html integer : 可选
    • 是否包含 HTML
    • 可选值:0和1
    • 默认 0
  • png integer 可选
    • 是否包含 PNG
    • 可选值:0和1
    • 默认 0
  • jpeg integer 可选
    • 是否包含JEPG
    • 可选值:0和1
    • 默认 0
  • iframes integer 可选
    • 是否包含iframes 
    • 可选值:0和1
    • 默认 0
  • script integer 可选
    • 是否包含自定义js执行的最终结果,查看相关文档
    • 可选值:0和1
    • 默认 0
  • console integer 可选
    • 是否包含自定义js 中的console信息
    • 可选值:0和1
    • 默认 0
  • history integer 可选
    • 是否包含 request 和 response 的历史记录(仅 webpage main frame,不包括 图片 和 ajax )
    • 可选值:0和1
    • 默认 0
    • 在这些历史记录中能获取到 状态码 和 请求头,如果要获取所有的 request 和 response,可以使用参数:har
  • har integer 可选
    • 是否包含 HAR
    • 可选值:0和1
    • 默认 0
    • 开启时,将获取与 render.har 相同的数据,结果中是否包含 request contents 和 response contents 可以通过  ‘request_body’ 和 ‘response_body’ 设置
  • request_body int 可选
    • 当 ‘har’ and ‘history’为0时,此选项无效
  • response_body int 可选
    • 当 ‘har’ and ‘history’为0时,此选项无效

 

render.json 的例子

# full information
curl 'http://localhost:8050/render.json?url=http://domain.com/page-with-iframes.html&png=1&html=1&iframes=1'

# HTML and meta information of page itself and all its iframes
curl 'http://localhost:8050/render.json?url=http://domain.com/page-with-iframes.html&html=1&iframes=1'

# only meta information (like page/iframes titles and urls)
curl 'http://localhost:8050/render.json?url=http://domain.com/page-with-iframes.html&iframes=1'

# render html and 320x240 thumbnail at once; do not return info about iframes
curl 'http://localhost:8050/render.json?url=http://domain.com/page-with-iframes.html&html=1&png=1&width=320&height=240'

# Render page and execute simple Javascript function, display the js output
curl -X POST -H 'content-type: application/javascript' \
    -d 'function getAd(x){ return x; } getAd("abc");' \
    'http://localhost:8050/render.json?url=http://domain.com&script=1'

# Render page and execute simple Javascript function, display the js output and the console output
curl -X POST -H 'content-type: application/javascript' \
    -d 'function getAd(x){ return x; }; console.log("some log"); console.log("another log"); getAd("abc");' \
    'http://localhost:8050/render.json?url=http://domain.com&script=1&console=1'

 

 

默认返回 URL、requested URL、page title、frame结构:

{
    "url": "http://crawlera.com/",
    "geometry": [0, 0, 640, 480],
    "requestedUrl": "http://crawlera.com/",
    "title": "Crawlera"
}

 

设置 html=1时:

{
    "url": "http://crawlera.com/",
    "geometry": [0, 0, 640, 480],
    "requestedUrl": "http://crawlera.com/",
    "html": "<!DOCTYPE html><!--[if IE 8]>....",
    "title": "Crawlera"
}

 

设置 png=1,获取base64编码的PNG 屏幕截图。

{
    "url": "http://crawlera.com/",
    "geometry": [0, 0, 640, 480],
    "requestedUrl": "http://crawlera.com/",
    "png": "iVBORw0KGgoAAAAN...",
    "title": "Crawlera"
}

 

设置 iframes=1

{
    "geometry": [0, 0, 640, 480],
    "frameName": "",
    "title": "Scrapinghub | Autoscraping",
    "url": "http://scrapinghub.com/autoscraping.html",
    "childFrames": [
        {
            "title": "Tutorial: Scrapinghub's autoscraping tool - YouTube",
            "url": "",
            "geometry": [235, 502, 497, 310],
            "frameName": "<!--framePath //<!--frame0-->-->",
            "requestedUrl": "http://www.youtube.com/embed/lSJvVqDLOOs?version=3&rel=1&fs=1&showsearch=0&showinfo=1&iv_load_policy=1&wmode=transparent",
            "childFrames": []
        }
    ],
    "requestedUrl": "http://scrapinghub.com/autoscraping.html"
}

 

设置script=1

{
    "url": "http://crawlera.com/",
    "geometry": [0, 0, 640, 480],
    "requestedUrl": "http://crawlera.com/",
    "title": "Crawlera",
    "script": "result of script..."
}

 

设置console=1

{
    "url": "http://crawlera.com/",
    "geometry": [0, 0, 640, 480],
    "requestedUrl": "http://crawlera.com/",
    "title": "Crawlera",
    "script": "result of script...",
    "console": ["first log message", "second log message", ...]
}

 

 

execute

执行自定义脚本并返回结果

render.htmlrender.pngrender.jpegrender.har 和 render.json已经能满足大多数情况下的使用了,但某些情况下,还是不能满足我们的需求。这时我们可以使用 Splash Scripts 来自定义 endpoint。

参数:

  • lua_source string : 必须
  • timeout float 可选
  • allowed_domains string optional
  • proxy string optional
  • filters string optional
  • save_args JSON array or a comma-separated string optional
    •  同render.html  的 save_args
    • 不仅可以缓存Splash的默认参数,也可以缓存所有你想设置的参数
  • load_args JSON object or a string optional
    • render.html  的 load_args
    • 不仅可以取出Splash的默认参数,也可以缓取出所有你设置过的参数

不仅可以传这些默认的参数,你也可以自己设置想要的参数。所有传递给 execute的参数都是可用的。

 

run

与 execute 相同,但在 lua_source 会自动封装进 function main(splash, args) ... end 中 。

例如,你发送以下脚本给execute:

function main(splash, args)
    assert(splash:go(args.url))
    assert(splash:wait(1.0))
    return splash:html()
end

 

和 发送以下脚本给 run 效果一样:

assert(splash:go(args.url))
assert(splash:wait(1.0))
return splash:html()

 

 

在页面中执行自定义脚本

也可以在 相关文档 中查阅

Splash 支持在页面中执行自定也的js代码。js通常是在页面渲染完成后执行的,但是Splash允许在页面正在渲染时,通过js去修饰正在渲染的页面。

通过  js_source 参数 来设置要执行的js。

提醒:浏览器和代理限制了GET方法能发送的数据量,所以,最好使用 content-type: application/json 的POST请求。

例子:

# Render page and modify its title dynamically
curl -X POST -H 'content-type: application/json' \
    -d '{"js_source": "document.title=\"My Title\";", "url": "http://example.com"}' \
    'http://localhost:8050/render.html'

 

content-type 为 application/javascript’ 时:

# Render page and modify its title dynamically
curl -X POST -H 'content-type: application/javascript' \
    -d 'document.title="My Title";' \
    'http://localhost:8050/render.html?url=http://domain.com'

 

如果需要获取 js执行的结果可以使用 render.json ,设置 script=1

Javascript Profiles

Splash 可以使用 " javascript profiles " 预加载 js 文件。定义在配置文件中的 js 文件 在请求中js代码被执行前,在页面加载完成后被执行。

预加载文件可以在用户的 POST’ed 代码中使用。

开启 js 配置文件支持:

python3 -m splash.server --js-profiles-path=/etc/splash/js-profiles

 

See also: Splash Versions.

然后以配置文件的名称创建一个目录,将js文件放在这个目录下面(请使用 utf-8 编码),文件按他们出现在 filesystem 中的顺序加载。例:

/etc/splash/js-profiles/
                    mywebsite/
                          lib1.js

 

通过在请求中设置参数 js=mywebsite 来应用 js 配置文件。

curl -X POST -H 'content-type: application/javascript' \
    -d 'myfunc("Hello");' \
    'http://localhost:8050/render.html?js=mywebsite&url=http://domain.com'

 

提醒:这个例子假定了 lib1.js 中定义了 myfunc 这个函数。

 

Javascript Security

如果使用 --js-cross-domain-access 开启 Splash:

$ docker run -it -p 8050:8050 scrapinghub/splash --js-cross-domain-access

 

则 js 代码被允许访问来自 security origin 的 iframes 中的内容,尽管与原页面不同源。这在浏览器中通常是不被允许的。

这个特性有利于爬取页面时,提取iframe中的内容。例:

curl -X POST -H 'content-type: application/javascript' \
    -d 'function getContents(){ var f = document.getElementById("external"); return f.contentDocument.getElementsByTagName("body")[0].innerHTML; }; getContents();' \
    'http://localhost:8050/render.html?url=http://domain.com'

允许跨源js调用有潜在的风险,有可能会暴露保密的信息(例如:cookies)。在跨域安全被禁用时,一些网站不会加载。所以这个特性默认被关闭。

 

Request Filters

Splash 可以基于 Adblock Plus  规则,过滤请求。你可以使用 EasyList 提供的过滤器移除 广告 和 跟踪,也可以手写过滤器来阻塞一些请求,例如:images、mp3 files、custom fonts等。

通过以下方式开启 Splash 的 request filters :

python3 -m splash.server --filters-path=/etc/splash/filters

 

filters-path 路径下存放 包含有 用 Adblock Plus 规则定义的过滤器的 .txt文件,你也可以从  EasyList 下载 easylist.txt,然后存放在这个位置。

例子(过滤器阻止request加载ttf和woff格式的自定义字体):

! put this to a /etc/splash/filters/nofonts.txt file
! comments start with an exclamation mark

.ttf|
.woff|

 

在请求中使用该文件:

curl 'http://localhost:8050/render.png?url=http://domain.com/page-with-fonts.html&filters=nofonts'

 

要使用多个过滤器文件时:

curl 'http://localhost:8050/render.png?url=http://domain.com/page-with-fonts.html&filters=nofonts,easylist'

 

如果 --filters-path 目录下存在 default.txt ,则 filters 在没有指定的情况下会默认使用该文件。如果不想 使用这个特性,请设置:filters=none

仅仅 related resources 会被过滤,‘main’ page 的加载不会被阻塞。如果你想知道是否过滤 'main' page ,可以在发送命令给splash前检查该 url 是否应该被过滤。python 可以使用 adblockparser

学习 Adblock Plus 过滤器语法:

注:如果你想过滤图片,可以使用 images 参数,不一定非要使用过滤器。使用 images 参数能过滤掉过滤器很难过滤的图片。

警告:如果你有大量过滤器需要使用,请安装 pyre2。如果没有安装 pyre2 ,splash 将依赖 stdlib 的 re 模块,而 re2 模块的速度是 re 模块的1000倍,你看着办吧。另外,不要使用 re2 的 0.2.20 版本,请尽量使用最新版本。

 

Proxy Profiles

splash 支持通过 "proxy profiles"  为每个设置了 "proxy" 参数的请求设置代理规则。

开启 代理文件 支持:

python3 -m splash.server --proxy-profiles-path=/etc/splash/proxy-profiles
# 如果你使用docker,查阅 Folders Sharing

 

然后在  “proxy profile” 目录下创建 一个 .ini 的代理配置文件(例如:/etc/splash/proxy-profiles/mywebsite.ini),例:

[proxy]

; required
host=proxy.crawlera.com
port=8010

; optional, default is no auth
username=username
password=password

; optional, default is HTTP. Allowed values are HTTP and SOCKS5
type=HTTP

[rules]
; optional, default ".*"
whitelist=
    .*mywebsite\.com.*

; optional, default is no blacklist
blacklist=
    .*\.js.*
    .*\.css.*
    .*\.png

 

whitelist 和 blacklist 通过空行隔开,内容为 re 表达式。如果 url 在白名单中,并且不在黑名单中,则是使用 [proxy] 中的代理。

应用 配置文件 中的代理设置:

curl 'http://localhost:8050/render.html?url=http://mywebsite.com/page-with-javascript.html&proxy=mywebsite'

 

 如果配置文件目录下存在 default.ini 文件,则即使没有使用参数 proxy ,也会默认使用default.ini中的代理设置。如果需要关闭这个特性,请设置 proxy=none

 

Other Endpoints

 _gc

 

curl -X POST http://localhost:8050/_gc

 

 

 

 运行 Python garbage collector,并且清空 WebKit 缓存。

 

_debug

 获取Splash实例的debug的信息,包括:max RSS used, number of used file descriptors, active requests, request queue length, counts of alive objects

curl http://localhost:8050/_debug

 

 

_ping

 ping Splash 实例,返回 ‘ok’,max RSS (最大常驻物理内存) 被使用

curl http://localhost:8050/_debug