Splash
跟以前咱们介绍的 Selenium ( 参考 Selenium 与自动化测试 —— 《Selenium 2 自动化测试实战》读书笔记) 很相似,均可以理解成一个浏览器,提供网页动态渲染(css、javascript、flash 等)服务,而且都支持 HTTP API 与之交互。javascript
但不一样点在于:css
Splash 更轻量级,但缺点是功能没有Selenium丰富。(因此 Selenium 才称得上是自动化测试框架,Splash更多的算一种网页渲染服务)html
Splash 的安装、配置、使用更简单java
Splash 支持异步,能提升爬取效率node
文档地址:https://splash.readthedocs.io/en/stable/python
注意:事先安装好 docker。web
docker run -p 8050:8050 scrapinghub/splash
docker
部署在远程服务器记得加 -d 参数,它表明将 Docker 容器以守护态运行,这样在断开远程服务器链接后,不会终止 Splash 服务的运行。json
安装好后,打开 http://localhost:8050
便可访问,页面以下:api
本文安装版本为 v3.4。
能够在此 web 页面来使用,也能够用下面介绍的 API 调用方式,更灵活。
http://localhost:8050/render.html?url=https://www.baidu.com http://localhost:8050/render.png?url=https://www.baidu.com http://localhost:8050/render.jpeg?url=https://www.baidu.com http://localhost:8050/render.har?url=https://www.baidu.com http://localhost:8050/render.json?url=https://www.baidu.com
除了上面指定的最简单的url、render类型,还能够经过 Lua 脚本执行更复杂的渲染操做和交互逻辑(即用 execute)。
咱们用 python 代码为例:
import requests from urllib.parse import quote lua = """ function main(splash) return 'hello' end """ url = 'http://localhost:8050/execute?lua_source=' + quote(lua) response = requests.get(url) print(response.text)
下面咱们对 Lua 脚本的写法作更多的介绍。
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
接下来针对这个最基本的 demo,来展开介绍。
main 函数就是 splash 默认要调用的函数,因此这里保持固定写法就好。
而 main 的返回值,既能够是字典形式,也能够是字符串形式,最后都会转化为 HTTP Response。
splash 相似于 Selenium 中的 WebDriver 对象。
上面提到的 main 函数的第二个参数 args 实际上是 splash 对象的其中一个属性,即:
splash.args = args
splash.resource_timeout = 0.1 - 设置超时时间。若是设置为 0 或 nil (相似 Python 中的None),表明不检测超时。
此属性适合在网页加载速度较慢的状况下设置
splash.js_enabled = false - 是否执行 js(默认为 ture)
splash.images_enabled = false 是否加载图片(默认为 ture)
当心 image 不加载致使个别 DOM 渲染出错
splash.plugins_enabled = false - 是否加载浏览器插件,如 Flash 插件 (默认 false)
splash.scroll_position = {x=100, y=200} = 页面上下或左右滚动
go() - 模拟 GET 和 POST 请求
http_get() - 模拟 GET 请求
http_post() - 模拟 POST 请求
function main(splash, args) -- 错误处理 local ok, reason = splash:go{"http://httpbin.org/post", http_method="POST", body="name=Germey"} if ok then return splash:html() end end
wait() - 等待。相似 python 中的 sleep(多与 go 配合,紧接在 go 后面)
为何 splash 没有 selenium 的 expected_conditions(预期条件判断)方法,如presence_of_element_located。
call_later() - 相似 JavaScript 的 settimeout
evaljs() - 执行 js 代码
local title = splash:evaljs("document.title")
runjs() 跟 evaljs() 功能相似,只不过语义上更倾向于只调用不关心返回值。
autoload() 跟 evaljs() 功能相似,只不过语义上更倾向于预先加载。
jsfunc() - JavaScript 方法转换为 Lua 脚本
这个好,毕竟我 Lua 语法不熟。
function main(splash, args) local get_div_count = splash:jsfunc([[ function () { var body = document.body; var divs = body.getElementsByTagName('div'); return divs.length; } ]]) splash:go("https://www.baidu.com") return("There are %s DIVs"):format(get_div_count()) end
url() - 获取/设置 url
html() / set_content() - 获取/设置 html 内容
splash:set_content ("
hello ")
png() / jpeg() - 获取页面截图
har() - 获取页面加载过程描述
get_cookies() / add_cookie() / clear_ cookies() - 获取/设置/清除 html 内容
splash:add_cookie({"sessionid", "asdasd", "/", domain="http://example.com" })
set_user_agent() - 设置 user-agent
set_custom_headers() - 设置 header
自定义程度更高,能够设置 user_agent、cookies 等等
splash:set_custom_headers({ ["User-Agent"] = "Splash", ["Site"] = "Splash", })
get_viewport_size() / set_viewport_size(width, height) - 获取/设置页面大小
set_viewport_full() - 设置全屏
select() - css 选择器 (选择首个)
input = splash:select("#kw”) -- 点击控件 input:mouse_click() -- 给控件输入文本 input:send_text('Splash')
selectAll() - css 选择器 (选择所有)
-- 经过 css 选择器选中了节点的正文内容,随后遍历了全部节点,将其中的文本获取下来 local texts = splash:select_all('.quote .text') local results = {} for index, text in ipairs(texts) do results[index] = text.node.innerHTML end
待写。具体可看原书。
《Python 3网络爬虫开发实战》