JavaScript动态渲染页面爬取之Splash

news2025/1/17 1:23:35

Splash是一个 JavaScript渲染服务,是一个含有 HTTP API的轻量级浏览器,它还对接了 Python 中的 Twisted 库和 OT库。利用它,同样可以爬取动态渲染的页面。

功能介绍

利用 Splash,可以实现如下功能:

  • 异步处理多个网页的渲染过程:
  • 获取渲染后页面的源代码或截图;
  • 通过关闭图片渲染或者使用 Adblock规则的方式加快页面渲染的速度;
  • 执行特定的 JavaScript 脚本;
  • 通过 Lua 脚本控制页面的渲染过程;
  • 获取页面渲染的详细过程并以HAR(HTTPArchive)的格式呈现出来。

接下来,我们一起了解 Splash 的具体用法。

准备工作

请确保 Splash 已经正确安装好并可以在本地 8050端口上正常运行。安装方法可以参考 https:/setup.
scrape.center/splash。

win10 docker安装
  1. 去docker官网下载,但请一定要注意你Windows笔记本电脑版本一定要和docker匹配,否则会报错:
    在这里插入图片描述
  2. 查看自己windows版本
    检查 Windows 版本:按 Win + R 键,输入 winver,然后点击“确定”。这将显示一个窗口,其中包含您当前使用的 Windows 版本信息。

在这里插入图片描述

  1. 官网找一个合适的版本,一般历史版本可能官网不好找,点击这里找个适合的版本 下载。

  2. 安装包下载之后直接双击安装即可,不过可能会报错:
    在这里插入图片描述

  3. 去给出的网址下载WSL2,安装即可。

splash安装

有了 Docker,只需要一键启动 Splash 即可,命令如下:

docker run -p 8050:8050 scrapinghub/splash

问题1:

docker: Error response from daemon: Get "https://registry-1.docker.io/v2/": context deadline exceeded.

我们可以配置国内的镜像,尽可能把所有的镜像都配置上,否则不是慢就是依然下载不下来:

 "registry-mirrors": [
    "https://registry.docker-cn.com",
    "http://hub-mirror.c.163.com",
    "https://docker.mirrors.ustc.edu.cn",
    "https://cr.console.aliyun.com",
    "https://mirror.ccs.tencentyun.com",
    "https://registry.docker-cn.com",
    "http://hub-mirror.c.163.com",
    "https://docker.mirrors.ustc.edu.cn/",
    "https://yxzrazem.mirror.aliyuncs.com",
    "https://docker.kubesre.xyz",
    "https://dc.j8.work",
    "https://docker.registry.cyou",
    "https://docker.hlyun.org",
    "https://docker.chenby.cn",
    "https://docker.jsdelivr.fyi",
    "https://docker-mirrors.mjjman.com",
    "https://docker.kubesre.xyz",
    "https://huecker.io",
    "https://dockerhub.timeweb.cloud",
    "https://docker.registry.cyou",
    "https://docker-cf.registry.cyou",
    "https://dockercf.jsdelivr.fyi",
    "https://dockertest.jsdelivr.fyi",
    "https://2a6bf1988cb6428c877f723ec7530dbc.mirror.swr.myhuaweicloud.com",
    "https://docker.m.daocloud.io",
    "https://hub-mirror.c.163.com",
    "https://mirror.baidubce.com",
    "https://your_preferred_mirror",
    "https://dockerhub.icu",
    "https://docker.registry.cyou",
    "https://docker-cf.registry.cyou",
    "https://dockercf.jsdelivr.fyi",
    "https://docker.jsdelivr.fyi",
    "https://dockertest.jsdelivr.fyi",
    "https://mirror.aliyuncs.com",
    "https://dockerproxy.com",
    "https://mirror.baidubce.com",
    "https://docker.m.daocloud.io",
    "https://docker.nju.edu.cn",
    "https://docker.mirrors.sjtug.sjtu.edu.cn",
    "https://docker.mirrors.ustc.edu.cn",
    "https://mirror.iscas.ac.cn",
    "https://docker.rainbond.cc"
  ]

经过我的测试,发现下载到一半依然报错,于是只能用VPN去下载了。

安装完成之后会有类似的输出结果:
在这里插入图片描述
这时我们打开:http://localhost:8050 即可看到 Splash 的主页,如图所示:
在这里插入图片描述
当然 Splash 也可以直接安装在远程服务器上,我们在服务器上运行以守护态运行 Splash 即可,命令如下:

docker run -d -p 8050:8050 scrapinghub/splash

在这里多了一个 -d 参数,它代表将 Docker 容器以守护态运行,这样在中断远程服务器连接后不会终止 Splash 服务的运行。

实例引入

上面我们打开http://localhost:8050 即可看到 Splash 的主页,右侧呈现的是一个渲染示例,可以看到其上方有一个输人框,默认显示文字是http://google.com,我们将其换成 htps://www.baidu.com 测试一下,换完内容后单击 Render me! 按钮,开始渲染,结果如下图所示。
在这里插入图片描述
渲染结果中包含渲染截图、HAR 加载统计数据和网页的源代码。Splash 染了整个网页,包括CSS、JavaScript 的加载等,最终呈现的页面和在浏览器中看到的完全一致。那么,这个过程由什么控制呢?我们返回首页,可以看到这样一段脚本:

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

这个脚本是用Lua语言写的。即使不懂Lua语言的语法,也能大致看懂脚本的表面意思,首先调用go方法加载页面,然后调用 wait 方法等待了一定时间,最后返回了页面的源代码、截图和 HAR 信息。

至此,我们大体了解了 Splash 是通过 Lua 脚本控制页面的加载过程,加载过程完全模拟浏览器最后可返回各种格式的结果,如网页源码和截图等。

接下来,我们就了解一下 Lua 脚本的写法以及相关 API的用法。

Splash Lua 脚本

Splash 能够通过 Lua 脚本执行一系列渲染操作,因此我们可以用它模拟 Chrome、PhantomJS,先了解一下 Splash Lua 脚本的入口和执行方式。

  • 入口及返回值

来看一个基本实例:

function main(splash, args)
	splash:go("http://www.baidu.com")
	splash:wait(0.5)
	local title = splash:evaljs("document.title")
	return {title=title}
end

将这段代码粘贴到上图中的代码编辑区域,然后单击 Render me! 按钮,返回结果如下图所示。
在这里插入图片描述
可以看到,渲染结果中包含网页的标题。这里我们通过evaljs 方法传人了 JavaScript 脚本,而document.title 返回的就是网页的标题,evaljs 方法执行完毕后将标题赋值给 title 变量,随后将其返回。

注意,我们在这里定义的方法叫 main。这个名称是固定的,Splash会默认调用这个方法。main方法的返回值既可以是字典形式,也可以是字符串形式,最后都会转化为Splash的 HTTP 响应,例如:

function main(splash)
	return {hello="world!"}
end

返回的是字典形式的内容。下面的代码:

function main(splash)
	return 'hello'
end

返回的是字符串形式的内容。

  • 异步处理

Splash 支持异步处理,但是并没有显式地指明回调方法,其回调的跳转是在内部完成的。示例如下:

function main(splash, args)
  local example_urls = {"www.baidu.com","www.taobao.com","www.zhihu.com"}
  local urls = args.urls or example_urls
  local results = {}
  for index,url in ipairs(urls) do
    local ok,reason = splash:go("http://" .. url)
    if ok then
      splash:wait(2)
      results[url] = splash:png()
		end
  end
  return results
end

运行这段代码后的返回结果是代码中3个网站的页面截图,如下图所示。
在这里插入图片描述

代码中调用的 wait 方法类似于 Python 中的 sleep 方法,参数是等待的秒数。当 Splash 执行到此方法时,会转而处理其他任务,在等待参数指定的时间后再回来继续处理。

这里值得注意的是,Lua 脚本中的字符串拼接和 Python 中不同,它使用的是“…”操作符,而不是66リ如果有必要,可以简单了解一下 Lua 脚本的语法,详见 http:/www.runoob.com/ua/lua-basic-syntax.html.另外,这里设置了加载页面时的异常检测。80方法会返回加载页面的结果状态,如果返回的状态码是 4xx或 5xx,那么 ok 变量为空,就不会返回加载后的图片。

splash 对象的属性

能够注意到,前面例子中 main方法的第一个参数是 splash,这个对象非常重要,类似于Selenium中的 webDriver 对象,我们可以调用它的一些属性和方法来控制加载过程。接下来,先看 splash 的属性。

  • args 属性

该属性用于获取页面加载时配置的参数,例如请求 URL。对于 GET请求,args 属性还可以用于获取 GET请求的参数;对于POST请求,args属性还可以用于获取表单提交的数据。此外,Splash 支持将 main 方法的第二个参数直接设置为 args,例如:

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

这里的第二个参数 args 就相当于 splash.args 属性,以上代码等价于:

function main(splash)
	local url=splash.args.url
end
  • js_enabled 属性

这个属性是 Splash 执行 JavaScript 代码的开关,将其设置为 true 或 false 可以控制是否执行JavaScript 代码,默认取 true。例如:

function main(splash, args)
	splash:go("https://www.baidu.com" )
	splash.js enabled=false
	local title = splash:evaljs("document.title")
	return {title=title}
end

这里我们将 is enabled 设置为 false,代表禁止执行 JavaScript代码,然后重新调用 evaljs 方法执行了 JavaScript 代码,此时运行这段代码,就会抛出异常:
在这里插入图片描述
不过,我们一般不设置此属性,默认开启。

  • resource_timeout 属性

此属性用于设置页面加载的超时时间,单位是秒。如果设置为0或nil(类似Python 中的None).

代表不检测超时。示例如下:

function main(splash)
	splash.resource_timeout = 0.1
	assert(splash:go('https://www.taobao.com'))
	return splash:png()
end

这里将超时时间设置为了 0.1秒。意味着如果在0.1秒内没有得到响应,就抛出异常:
在这里插入图片描述
此属性适合在页面加载速度较慢的情况下设置。如果超过某个时间后页面依然无响应,则直接抛出异常并忽略。

  • images_enabled 属性

此属性用于设置是否加载图片,默认是加载。禁用该属性可以节省网络流量并提高页面的加载速度,但是需要注意,这样可能会影响 JavaScript 渲染。因为禁用该属性之后,它的外层 DOM 节点的高度会受影响,进而影响 DOM 节点的位置。当JavaScript 对图片节点执行操作时,就会受到影响。

另外有一点值得注意,Spiash会使用缓存。意味着即使禁用images_enabled属性,一开始加载出来的网页图片也会在重新加载页面后显示出来,这种情况下直接重启Splash 即可。

禁用 images_enabled 属性的示例如下:

function main(splash, args)			
	splash.images_enabled=false
	assert(splash:go('https://www.jd.com'))
	return{png=splash:png()}
end

这样返回的页面截图不会带有任何图片,加载速度也会快很多。

  • plugins_enabled 属性

此属性用于控制是否开启浏览器插件(如 Flash 插件 ),默认取 false,表示不开启。可以使用如下代码开启/关闭 plugins_enabled:

splash.plugins enabled = true/false
  • scroll_position属性

此属性可以控制页面上下滚动或左右滚动,是一个比较常用的属性。示例如下:

function main(splash, args)
	assert(splash:go('https://www.taobao.com'))
	splash.scroll_position={y=400}
	return {png=splash:png()}
end

这样可以控制页面向下滚动 400 像素值,运行结果如下图所示。
在这里插入图片描述

如果要让页面左右滚动,可以传入x参数,代码如下:

splash.scroll_position={x=100,y=200}

splash 对象的方法

除了前面介绍的属性,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_method:请求方法,是可选参数,默认为GET,同时支持 POST。口 body:http_method为POST时的表单数据,使用的Content-type为application/json,是可选参数,默认为空。
  • formdata:http_method 为 POST 时的表单数据,使用的 Content-type 为 application/x-www-form-urlencoded,是可选参数,默认为空。

该方法的返回值是ok变量和 reason 变量的组合,如果 ok为空,代表页面加载出现了错误,reason中包含错误的原因,否则代表页面加载成功。示例如下:

function main(splash, args)
  local ok, reason = splash:go{"http://www.httpbin.org/post", http_method="PosT", body="name-Germey"}
  if ok then
  	return splash:html()
  end
end

这里我们模拟了一个POST请求,并传人了表单数据,如果页面加载成功,就返回页面的源代码。
运行结果如下:
在这里插入图片描述

可以看到成功实现了POST请求并发送了表单数据。

  • wait方法

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

ok, reason=splash:wait{time, cancel_on_redirect=false, cancel_on_error=true}

对其中各参数的说明如下。

  • time:等待的时间,单位为秒。
  • cancel_on_redirect:如果发生了重定向就停止等待,并返回重定向结果,是可选参数,默认为 false。
  • cancel_on_error:如果页面加载错误就停止等待,是可选参数,默认为 false。

其返回值同样是 ok 变量和 reason 变量的组合。
我们用一个实例感受一下:

function main(splash)
	splash:go("https://www.taobao.com")
	splash:wait(2)
	return {html=splash:html()}
end

执行如上代码,可以访问淘宝页面并等待2秒,随后返回页面源代码。

  • jsfunc 方法

此方法用于直接调用 JavaScript 定义的方法,但是需要用双中括号把调用的方法包起来,相当于实现了从 JavaScript 方法到 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

这段代码的运行结果如下:
在这里插入图片描述

这里我们先声明了一个 JavaScript定义的方法 get div_count,然后在页面加载成功后调用此方法计算出了页面中 div 节点的个数。

关于从 JavaScript方法转换到Lua脚本的更多细节,可以参考官方文档:https://splash.readthedocs.
io/en/stable/scripting-ref.html#splash-jsfunc。

  • evaljs 方法

此方法用于执行 JavaScript 代码并返回最后一条 JavaScript 语句的返回结果,其用法如下:

result=splash:evaljs(js)

例如,可以用下面的代码获取页面标题:

local title =splash:evaljs("document.title")
  • runjs 方法

此方法用于执行JavaScript代码,它的功能与evalis方法类似,但更偏向于执行某些动作或声明某些方法。例如:

function main(splash, args)
  splash:go("https://www.baidu.com")
	splash:runjs("foo =function(){return 'bar'}")
  local result=splash:evaljs("foo()")
	return result
end

这里我们先用 runjs 方法声明了一个 JavaScript 方法 foo,然后通过 evaljs 方法调用 foo 方法得到的结果。
运行结果如下:
在这里插入图片描述

可以看到,这里我们成功模拟了发送POST请求,并发送了表单数据。

  • html方法

此方法用于获取页面的源代码,是一个非常简单且常用的方法,示例如下:

function main(splash, args)
  splash:go("https://www.httpbin.org/get")
  return splash:html()
end

运行结果如下:
在这里插入图片描述

  • png 方法

此方法用于获取 PNG 格式的页面截图,示例如下:

function main(splash, args)
	splash:go("https://www.taobao.com")
	return splash:png()
end
  • jpeg 方法

此方法用于获取 JPEG 格式的页面截图,示例如下:

function main(splash, args)
	splash:go("https://www.taobao.com")
	return splash:jpeg()
end
  • har 方法

此方法用于获取页面加载过程的描述信息,示例如下:

function main(splash, args)
	splash:go("https://www.baidu.com")
  return splash:har()
end

运行结果如下图所示:
在这里插入图片描述
这张图里显示了百度页面加载过程中的每个请求记录的详情。

  • url方法

此方法用于获取当前正在访问的URL,示例如下:

function main(splash, args)
  splash:go("https://www.baidu.com")
  return splash:url()
end

运行结果如下:
在这里插入图片描述

  • set_user_agent 方法

此方法用于设置浏览器的 User-Agent,示例如下:

function main(splash)
	splash:set_user_agent('Splash')
  splash:go("http://www.httpbin.org/get")
  return splash:html()
end

这里我们将浏览器的 User-Agent 属性设置为了 Splash,运行结果如下:

在这里插入图片描述

可以看到,我们设置的 User-gent 属性值生效了。

  • select 方法

该方法用于选中符合条件的第一个节点,如果有多个节点符合条件,则只返回一个,其参数是CSS选择器。示例如下:

function main(splash)
  splash:go("https://www.baidu.com/")
  input =splash:select("#kw")
  input:send_text('Splash')
  splash:wait(3)
  return splash:png()
end

这里我们首先访问百度官网,然后用select 方法选中搜索框,随后调用 send_text 方法填写了文本,最后返回网页截图。运行结果如下图所示。
在这里插入图片描述
可以看到,我们成功填写了输入框。

  • select_all方法

此方法用于选中所有符合条件的节点,其参数是CSS选择器。示例如下:

function main(splash)
	local treat =require('treat')
  assert(splash:go("http://quotes.toscrape.com/"))
  assert(splash:wait(0.5))
  local texts = splash:select_all('.quote .text')
  local results={}
  for index,text in ipairs(texts)do
    results[index]= text.node.innerHTML
  end
  return treat.as_array(results)
end

在这里插入图片描述

可以发现,我们成功获取了10个节点的正文内容。

  • mouse_click方法

此方法用于模拟鼠标的点击操作,参数为坐标值x、y。我们可以直接选中某个节点直接调用此方法,示例如下:

function main(splash)
  splash:go("https://www.baidu.com/")
  input = splash:select("#kw")
  input:send_text('Splash')
  splash:wait(3)
  submit=splash:select('#su')
  submit:mouse_click()
	splash:wait(5)
  return splash:png()
end

这里我们首先选中页面的输入框,向其中输人文本 Splash,然后选中提交按钮,调用mouse click方法提交査询,之后等待5秒,就会返回页面截图,如下图所示。
在这里插入图片描述

可以看到,我们成功获取了查询后的页面内容,模拟了百度的搜索操作。

至此,splash对象的常用方法介绍完毕,还有一些方法这里不一一介绍了,更加详细和权威的说明可以参见官方文档 https://splash.readthedocs.io/en/stable/scripting-ref.html,此页面介绍了splash 对象的所有方法。另外,还有针对页面元素的方法,见官方文档 https://splash.readthedocs.io/en/stable/scriptingelement-object.html.

调用 Splash 提供的 API

前面我们介绍了 SplashLua脚本的用法,但这些脚本是在 Splash 页面里测试运行的,如何才能利用 Splash 渲染页面?Splash 怎样才能和 Python 程序结合使用并爬取 JavaScript 渲染的页面?

其实,Splash 给我们提供了一些 HTTP API,我们只需要请求这些 API 并传递相应的参数即可获取页面渲染后的结果,下面我们学习这些 API。

  • render.html

此 AP 用于获取 JavaScript 渲染的页面的 HTML代码,API地址是 Splash 的运行地址加上此 API的名称,例如 http://ocalhost:8050/renderhtml,我们可以用 curl 工具测试一下:

curl http://localhost:8050/render.html?url=https://www.baidu.com

我们给此 API传递了一个 ur1 参数,以指定渲染的 URL,返回结果即为页面渲染后的源代码。

import requests

url='http://localhost:8050/render.html?url=https://www.baidu.com'
response =requests.get(url)
print(response.text)

这样就可以成功输出百度页面渲染后的源代码了。
此 API还有其他参数,例如 wait,用来指定等待秒数。如果要确保页面完全加载出来,就可以设置此参数,例如:

import requests

url='http://localhost:8050/render.html?url=https://www.baidu.com&wait=5'
response =requests.get(url)
print(response.text)

增加等待时间后,得到响应的时间会相应变长,如这里我们等待大约5秒钟才能获取 JavaScript 渲染后的淘宝页面源代码。

另外,此API还支持代理设置、图片加载设置、请求头设置和请求方法设置,具体的用法可以参见官方文档 https://splash.readthedocs.io/en/stable/api.html#render-html。

  • render.png

此 API用于获取页面截图,其参数比 render.html 要多几个,例如 width 和 height 用来控制截图的宽和高,返回值是 PNG 格式图片的二进制数据。示例如下:

curl http://localhost:8050/render.png?url=https://ww.taobao.com&wait-5&width=1000&height=700

这里我们通过设置 width 和 height 参数,将页面截图的大小缩放为 1000x700 像素。如果用 Python 实现,可以将返回的二进制数据保存为 PNG 格式的图片,代码如下:

import requests

url = ('http://localhost:8050/render.png?url=https://www.jd.com&wait=5&width=1000&height=700')
response = requests.get(url)
with open('taobao.png', 'wb') as f:
    f.write(response.content)

得到的图片如下图所示。
在这里插入图片描述
这样我们就成功获取了京东首页渲染完成后的页面截图,详细的参数设置可以参考官网文档https://splash.readthedocs.io/en/stable/api.html#render-png.

  • render.jpeg

此 API和 render.png 类似,不过它返回的是 JPEG 格式图片的二进制数据
另外,此API比 render.png 多一个参数quality,该参数可以设置图片质量。

  • render.har

此 API用于获取页面加载的 HAR 数据,示例如下:

curl http://localhost:8050/render.har?url=https://www.jd.com&wait=5

运行结果非常多,是一个JSON格式的数据,里面包含页面加载过程中的 HAR 数据。

  • render.json

此 API 包含前面介绍的所有 render 相关的 API的功能,返回值是 JSON 格式的数据,示例如下:

curl http://localhost:8050/render.json?url=https://www.httpbin.org

这里返回了 JSON 格式的请求数据。
我们可以通过传入不同的参数控制返回结果。例如,传入html=1,返回结果会增加页面源代码;传人 png=1,返回结果会增加 PNG格式的页面截图;传人 har=1,返回结果会增加页面的 HAR数据。例如:

curl http://localhost:8050/render.json?url=https://www.httpbin.org&html=1&har=1

这样返回的结果中便会包含页面源代码和 HAR 数据。
此外,还有其他参数可以设置,可以参考官方文档 https://splash.readthedocs.io/en/stable/api.html#render-json.

  • execute

此 API才是最为强大的API。之前介绍了很多关于 SplashLua 脚本的操作,用此API即可实现与Lua 脚本的对接。
要爬取一般的 JavaScript 渲染页面,使用前面的 render.html 和 render.png 等 API 就足够了,但如果要实现一些交互操作,这些API还是心有余而力不足,就需要使用execute 了。
先实现一个最简单的脚本,直接返回数据:

function main(splash)
	return 'hello'
end

然后将此脚本转化为 URL编码后的字符串,拼接到execute后面,示例如下:

curl http://localhost:8050/execute?lua_source=function+main%28splash%29%0D%0A++return+%27he11o%27%0D%0Aend

运行结果如下:
hello

这里我们通过 lua_source 参数传递了转码后的 Lua 脚本,通过 execute 获取了脚本最终的执行结果。我们更加关心的是如何用 Python 实现上述过程,如果用 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)

运行结果如下:
hello

这里我们用 Python 中的三引号将Lua脚本括了起来,然后用 urllib.parse模块里的 quote方法对脚本进行 URL转码,之后构造了请求 URL,并将其作为 lua_source 参数传递,这样运行结果就会显示Lua 脚本执行后的结果。
我们再通过实例看一下:

import requests

from urllib.parse import quote

lua = '''
function main(splash)
    local treat =require("treat")
    local response = splash:http_get("http://www.httpbin.org/get")
    return {html=treat.as_string(response.body),
    url=response.url,status=response.status
    }
end
'''

url = 'http://localhost:8050/execute?lua_source=' + quote(lua)
response = requests.get(url)
print(response.text)

运行结果如下:

{"html": "{\n  \"args\": {}, \n  \"headers\": {\n    \"Accept-Encoding\": \"gzip, deflate\", \n    \"Accept-Language\": \"en,*\", \n    \"Host\": \"www.httpbin.org\", \n    \"User-Agent\": \"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/602.1 (KHTML, like Gecko) splash Version/10.0 Safari/602.1\", \n    \"X-Amzn-Trace-Id\": \"Root=1-678293a3-209dd02a23aa508c59709099\"\n  }, \n  \"origin\": \"111.19.92.180\", \n  \"url\": \"http://www.httpbin.org/get\"\n}\n", "url": "http://www.httpbin.org/get", "status": 200}

可以看到,返回结果是 JSON 形式的,我们成功获取了请求 URL、状态码和页面源代码。如此一来,之前所讲的 Lua 脚本就都可以用此方式与 Python 对接了,所有网页的动态渲染、模拟点击、表单提交、页面滑动、延时等待后的结果均可以自由控制获取细节,获取页面源代码和截图也都不在话下。

到现在为止,我们可以利用 Python 和 Splash 爬取 JavaScript渲染的页面了。除了 Selenium,Splash同样可以实现非常强大的渲染功能,同时它不需要浏览器便可渲染,使用起来非常方便。

负载均衡配置

用 Splash 爬取页面时,如果爬取的数据量非常大,任务非常多,那么只用一个 Splash 服务就会使压力非常大,此时可以考虑搭建一个负载均衡器把压力分散到多个服务器上,相当于多台机器、多个服务共同参与任务的处理,可以减小单个Splash 服务的压力。
由于篇幅原因,请移步 https://setup.scrape.center/splash-loadbalance 查看具体的配置方法。

总结

本篇博客中,我们全面地了解了 Splash 的基本用法。有了 Splash,可以将 JavaScript 动态渲染的操作完全托管到一个服务器上,爬虫爬取的时候不需要再依赖 Selenium 等库,整个业务逻辑会更加轻量级。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2277785.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

天机学堂2-高并发优化

day04-高并发优化 方案选择 实现了学习计划和学习进度的统计功能。特别是学习进度部分,为了更精确的记录用户上一次播放的进度,我们采用的方案是:前端每隔15秒就发起一次请求,将播放记录写入数据库。 在并发较高的情况下&#xf…

ROS2 准备工作(虚拟机安装,Ubuntu安装,ROS2系统安装)

准备工作 虚拟机安装 大家可以自行去安装VMware链接:https://pan.baidu.com/s/1KcN1I9FN--Sp1bUsjKqWVA?pwd6666 提取码:6666(提供者:零基础编程入门教程) 教程:【【2025最新版】VMware虚拟机安装教程,手把手教你免…

在一个地方待多久才会改变ip属地

‌在当今数字化时代,IP地址作为网络世界的“门牌号”,不仅承载着设备连接互联网的身份信息,还常常与地理位置相关联。随着人们频繁地迁徙、旅行或在不同地点工作,一个自然而然的问题浮现在许多人心头:究竟在一个地方待…

CCLINKIE转ModbusTCP网关,助机器人“掀起”工业智能的“惊涛骇浪”

以下是一个稳联技术CCLINKIE转ModbusTCP网关(WL-CCL-MTCP)连接三菱PLC与机器人的配置案例:设备与软件准备设备:稳联技术WL-CCL-MTCP网关、三菱FX5UPLC、支持ModbusTCP协议的机器人、网线等。 稳联技术ModbusTCP转CCLINKIE网关&…

QT在 MacOS X上,如何检测点击程序坞中的Dock图标

最近在开发MacOS的qt应用,在做到最小化系统托盘功能时,发现关闭窗口后再次点击程序坞中的Dock图标不能将主界面再显示出来。查询里很多资料,发现是QT自身的问题,没有做相关的点击Dock图标的处理。 于是我参考了国内和国外的这两篇…

langchain4j执行源码分析

要做大模型应用,不可避免会接触到langchain,但是langchain本身使用py实现,对于java用户上手体验不是很友好。继而出现了java版的langchain,即langchain-4j。这里我们用脑图分析一下其执行源码。

【案例81】NMC调用导致数据库的效率问题

问题现象 客户在使用NC系统时,发现系统特别卡顿。需要紧急排查。 问题分析 排查NMC发现,所有的线程都处于执行SQL层面,说明数据库当前出现了异常。查看数据库资源状态发现,Oracle相关进程CPU利用率达到了100%。 查看现在数据库…

PyTorch框架——基于深度学习YOLOv5神经网络水果蔬菜检测识别系统

基于深度学习YOLOv5神经网络水果蔬菜检测识别系统,其能识别的水果蔬菜有15种,# 水果的种类 names: [黑葡萄, 绿葡萄, 樱桃, 西瓜, 龙眼, 香蕉, 芒果, 菠萝, 柚子, 草莓, 苹果, 柑橘, 火龙果, 梨子, 花生, 黄瓜, 土豆, 大蒜, 茄子, 白萝卜, 辣椒, 胡萝卜,…

DFT可测性设置与Tetramax测试笔记

1 DFT 1.1 DFT类型 1、扫描链(SCAN): 扫描路径法是一种针对时序电路芯片的DFT方案.其基本原理是时序电路可以模型化为一个组合电路网络和带触发器(Flip-Flop,简称FF)的时序电路网络的反馈。 Scan 包括两个步骤,scan…

分布式ID的实现方案

1. 什么是分布式ID ​ 对于低访问量的系统来说,无需对数据库进行分库分表,单库单表完全可以应对,但是随着系统访问量的上升,单表单库的访问压力逐渐增大,这时候就需要采用分库分表的方案,来缓解压力。 ​…

28.找出字符串中第一个匹配项的下标【力扣】KMP前缀表 ≈ find() 函数、暴力解法

class Solution { public: //得到前缀表void getNext(int *next,string needle){int j0;for(int i1;i<needle.size();i){while(j>0 && needle[j]!needle[i]) jnext[j-1];//**j>0**>j0是出口if(needle[i]needle[j]) j;next[i]j;//若写入if中&#xff0c;则该…

当自动包布机遇上Profinet转ModbusTCP网关,“妙啊”,工业智能“前景无限

在自动化控制技术日新月异的当下&#xff0c;Profinet与ModbusTCP这两种协议在工业通信领域占据着举足轻重的地位。ModbusTCP是基于以太网的串行通信协议&#xff0c;而Profinet则是依托工业以太网的现场总线协议。它们在数据传输速度、实时性表现以及兼容性等方面各具特色。不…

ADC(Analog-to-digital converter)模拟-数字转换器

ADC简介 ADC&#xff08;Analog-to-Digital Converter&#xff09;&#xff0c;即模拟-数字转换器&#xff0c;是一种将模拟信号转换成数字信号的电子设备。它在现代电子系统中扮演着至关重要的角色&#xff0c;广泛应用于传感器信号处理、通信系统、医疗设备、工业自动化等多…

Uniapp判断设备是安卓还是 iOS,并调用不同的方法

在 UniApp 中&#xff0c;可以通过 uni.getSystemInfoSync() 方法来获取设备信息&#xff0c;然后根据系统类型判断当前设备是安卓还是 iOS&#xff0c;并调用不同的方法。 示例代码 export default {onLoad() {this.checkPlatform();},methods: {checkPlatform() {// 获取系…

TP4056锂电池充放电芯片教程文章详解·内置驱动电路资源!!!

目录 TP4056工作原理 TP4056引脚详解 TP4056驱动电路图 锂电池充放电板子绘制 编写不易&#xff0c;仅供学习&#xff0c;感谢理解。 TP4056工作原理 TP4056是专门为单节锂电池或锂聚合物电池设计的线性充电器&#xff0c;充电电流可以用外部电阻设定&#xff0c;最大充电…

平滑算法 效果比较

目录 高斯平滑 效果对比 移动平均效果比较: 高斯平滑 效果对比 右边两个参数是1.5 2 代码: smooth_demo.py import numpy as np import cv2 from scipy.ndimage import gaussian_filter1ddef gaussian_smooth_array(arr, sigma):smoothed_arr = gaussian_filter1d(arr, s…

Jenkins-简介/安装!

一. 关于持续集成&#xff1a; 持续集成(CI ) [ Continuous Integration ]&#xff0c;通俗来讲&#xff0c;就是一个能监控版本控制系统变化的工具&#xff0c;可以自动编译和测试集成的应用程序。出现问题&#xff0c;能够及时的通知相应人员。持续集成是一种思维工具集&…

Flutter中Get.snackbar避免重复显示的实现

在pubspec.yaml中引入依赖框架。 #GetX依赖注解get: ^4.6.5创建一个SnackBarManager管理类去管理每个提示框。 import package:get/get.dart; import package:flutter/material.dart;class SnackBarManager {factory SnackBarManager() > instance;static final SnackBarMa…

c#删除文件和目录到回收站

之前在c上遇到过这个问题&#xff0c;折腾许久才解决了&#xff0c;这次在c#上再次遇到这个问题&#xff0c;不过似乎容易了一些&#xff0c;亲测代码如下&#xff0c;两种删除方式都写在代码中了。 直接上完整代码&#xff1a; using Microsoft.VisualBasic.FileIO; using Sy…

微信小程序集成Vant Weapp移动端开发的框架

什么是Vant Weapp Vant 是一个轻量、可靠的移动端组件库&#xff0c;于 2017 年开源。 目前 Vant 官方提供了 Vue 2 版本、Vue 3 版本和微信小程序版本&#xff0c;并由社区团队维护 React 版本和支付宝小程序版本。 官网地睛&#xff1a;介绍 - Vant Weapp (vant-ui.gith…