Splash的使用


Splash的使用

Splash是一个JS渲染服务,本质是一个轻量级浏览器.建议Splash通过Docker安装.

Lua脚本

进入Splash,能看见这样一段代码:

function main(splash, args)
  assert(splash:go(args.url))
  assert(splash:wait(0.5))
  return {
    html = splash:html(),
    png = splash:png(),
    har = splash:har(),
  }
end

大致能看明白这段代码先执行了go方法,然后wait,返回值是html,png,har.
因此,通过修改这段代码,能实现更多的功能,具体细节请看笔者的Lua语言总结

入口和返回值

  • 入口:
    函数的入口固定为main,和c差不多

  • 返回值:
    返回值可以是字符串,也可以是字典,其形式分别如下:

    function main(splash, args)
        return `Hello World!` //字符串
    end
    
    function main(splash, args)
        return {hello=`Hello World!`} //字典
    end
    

    异步处理

    splash支持异步处理,在wait的时候会进行其他任务

    function main(splash, args)
        local urls = {"www.baidu.com","www.google.com","www.chrome.com"}
        local results = {}
        for index,url in pairs(urls) 
        do
          local ok,reason = splash:go(url)
          if ok 
          then
            splash.wait(2)
            results[url] = splash.png()
          end
        end
        return results
    end

splash对象的属性

main方法中的第一个参数splash及其重要,类似selenium中的webdriver对象.

args属性

main方法中的第二个参数args也是splashargs属性,所以:

function main(splash)
  local args = splash.args
end

也是正确的.
该属性可用于获取加载时的配置参数,例如url,对于POST请求可获取提交的表单,GET请求能获取请求参数.

js_enable属性

是否执行js的开关

recource_timeout属性

设置页面加载的超时时间,单位为,设置为0nil表示不检测超时

images_enable属性

用于设置是否加载图片,默认为true,如果不加载,可提高页面加载速度,但也可能影响js渲染.

plugins_enable属性

用于控制是否开启浏览器插件(比如时代眼泪Flash),默认不开启.

scroll_position属性

控制页面上下滚动或左右滚动

function main(splash)
  assert(splash:go(url))
  splash.scroll_position = {y=400} --控制上下滚动的像素为400
  return {png = splash.png()}
end

splash对象的方法

go方法

该方法用于请求某个链接,用于模拟GET请求和POST请求,同时支持传入请求头,表单等数据

ok,reason = splash:go(url,baseurl = nil, headers = nil, http_method = "GET", body = nil, formdata = nil)
  • url:请求的URL
  • baseurl: 资源加载的相对路径,可选参数
  • headers: 请求头
  • http_methos:请求方法,默认是GET,支持POST
  • body:POST方法时的表单数据,Content-typeapplication/json
  • formdata:POST方法时的表单数据,使用的Content-typeapplication/x-www-form-urlencoded

ok表示是否请求成功,如果失败,则ok为空,reason存储失败的原因

wait方法

该方法用于控制页面等待时间,用法如下:

ok,reason = splash:wait(time, cancel_on_redirect=false,concel_on_error=true)
  • time:等待时间,单位秒
  • cancel_on_redirect: 如果发生重定向则停止等待,并返回重定向结果,可选参数,默认为false
  • cancel_on_error:如果页面加载错误就停止等待,可选参数,默认为false

返回值和go方法类似,不再赘述

jsfunc方法

该方法直接调用JavaScript定义的方法,但是需要用双中括号把调用的方法扩起来.实现js方法和lua方法的转换,示例如下

function main(splash)
  local get_div_num = splash:jsfunc([[
    function () {
      var body = document.body;
      var divs = body.getElementByTagName("div");
      return divs.length;
    }
  ]])
  splash:go(url)
  return get_div_num();
end

evaljs方法

此方法用于执行js代码并返回最后一条js代码的返回结果,示例如下:

local title = splash:evaljs("document.title")

runjs方法

此方法也是用于执行js代码,和evaljs类似,但是其更偏向于执行某些动作或声明某些方法,示例如下:

local title = splash:runjs("foo = function(){return 'bar'}");

html方法

获取爬取页面的html源代码

png方法

获取爬取页面的png格式截屏

jpeg方法

获取JPEG格式的页面截屏

har方法

此方法用于获取页面加载过程中的描述信息.

url方法

用于获取当前正在访问网页的url.

set_user_agent方法

此方法用于设置浏览器的User-Agent

select方法

此方法用于选中符合条件的第一个节点,语法和css选择器类似

function main(splash)
  splash:go("www.baidu.com")
  input = splash:select("#kw") --id 为 kw 的节点
  return splash:text();
end

select_all方法

此方法返回所有符合条件的节点

mouse_click方法

相当于seleniumclick方法

send_text方法

相当于seleniumsend_keys方法

调用Splash提供的Api

前面是lua脚本得用法,但是要实现Splash渲染页面,和python交互获得我们想要的东西,因此,需要调用splash提供的api.
api地址格式是:
http://localhost:8050/{api}?url={}

render.html

api地址是:
http://localhost:8050/render.html?url={}
实例如下:

import requests
url = "https://www.baidu.com"
base_url = "http://localhost:8050/render.html?url={}"
response = requests.get(base_url.format(url))
print(response.text)

render.png

api地址是:
http://localhost:8050/render.png?url={}&width={}&height={}
其中widthheight用于控制截图的长宽.

render.jpeg

render.png类似

render.har

用于获取HAR数据返回值是json数据

render.json

API包含前面所有API的功能,基础功能为返回json格式的请求数据,通过增加不同的参数返回不同的结果.
http://localhost:8050/render.json?url=www.baidu.com&html=1,增加返回html代码的功能

execute

该方法的api为:

http://localhost:8050/execute?lua_source={}

实例如下:

import requests
from urllib.parse import quote

lua = """
function main(splash)
  local get_div_num = splash:jsfunc([[
    function () {
      var body = document.body;
      var divs = body.getElementByTagName("div");
      return divs.length;
    }
  ]])
  splash:go(url)
  return get_div_num();
end
"""
base_url = "http://localhost:8050/execute?lua_source="
url = base_url + quote(lua)
response = requests.get(url)
print(response.text())

Author: Dovahkiin
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source Dovahkiin !
  TOC