Scrapy-Splash-爬虫-同时返回图片与网页

本文最后更新于:2020年9月27日 晚上

环境

  • Splash 3.4.1
  • Scrapy-Splash 0.7.2
  • Windows10 专业版

问题

Splash如何同时返回html与图片

起因

在用Scrapy爬取网站时发现网页是一个动态渲染的画面
于是使用Splash爬取,查看png预览图,发现Splash已经得到正确的结果

Scrapy-Splash返回的 html 里也发现了对应的图片标签与路径
但直接通过图片路径来获取图片失败,提示为权限不足

解决问题

思路

在Splash获取到的预览画面中,图片已经正确的被渲染
那么只要让Splash同时返回图片和网页的数据就可以解决问题

过程

更改Scrapy-Splashlua代码参数

1
2
3
4
5
6
7
8
9
10
11
splash_lua_script = """
function main(splash, args)
assert(splash:go(args.url))
assert(splash:wait(0.5))
local preview_picture = splash:select('#slick-slide00 img')
return {
html = splash:html(),
png = preview_picture:png(),
}
end
"""

Splash只能通过使用 CSS 的方式来获取元素
这段代码的过程:获取网页,等待0.5s,通过CSS获取图片元素,并最终返回图片元素的截图

Scrapy-Splash请求提交

1
2
3
4
5
6
7
8
9
yield SplashRequest(
url=title_url,
callback=self.parse_title_page,
endpoint='execute',
args={
'lua_source': splash_lua_script,
'images': '1'
}
)

使用方法和在Scrapy里提交普通的Request一致。

需要注意的是endpoint这个参数
Scrapy-Splash有三种返回的Response类型类型:

实际返回类型 内容格式 endpoint
SplashResponse binary render.png
SplashTextResponse text render.html
SplashJsonResponse json render.json或execute

由于我希望同时返回图片和网页
若使用render.png则返回的二进制数据无法分开网页和图片
若使用render.html则压根不返回图片。
于是这里使用execute

回调函数中处理图片

1
2
import base64
base64.b64decode(response.data['png'])

使用execute后,返回的内容会是json,返回的图片会被记录为字符串。
为了将字符串转变回图片,需要使用base64转换会图片。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!