Splash动态数据抓取
最近学习爬虫过程中接触到了Splash,下面根据我所学的经历进行整理回放,相关的操作如下。期间遇到一些问题,本人自行解决了。
1.1 简介及安装
Splash是具有JavaScript渲染功能并带有HTTP API的轻量级浏览器,同时还对接了Python的网络引擎框架Twisted和QT库,让服务具有一步处理能力,以发挥webkit的并发能力。其实,Splash就是一个带有API接口的轻量级浏览器,使用它提供的API接口可以简单实现Ajax动态数据抓取。其实它与Selenium所实现的功能都是相同的,只不过实现的过程和原理有所不同。
Splash的安装是基于Docker应用容器引擎,Docker支持三大操作系统:Linux、MacOS和Windows。本人在MacOS环境下进行操作
# 启动Docker之后,输入如下命令,即可安装
root@liuxiaoweideAir liuxiaowei # docker run -d -p 8050:8050 scrapinghub/splash
# 在浏览器地址栏输入http://本机ip地址:8050即可打开splash
# 我的本机地址:192.168.68.242,端口8050
1.2 使用Splash的API接口
Splash的最大好处是可以执行JavaScript代码,将Ajax动态数据直接加载到网页上,无需开发者花费时间和精力分析Ajax请求,从而实现相关数据的抓取。Python可以使用Splash提供的API接口,从而实现Python与Splash之间的交互。Splash提供多种API接口实现不同的功能。
1.2.1 render.html获取JS加载后的网页信息
# render.html获取JS加载后的网页信息
# 启动Pycharm,新建一个python文件,代码如下
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36'
}
target_url = 'https://y.qq.com/portal/singer_list.html' # 以QQ音乐为例
url = 'http://192.168.68.242:8050/render.html?url='+target_url+'&wait=5'
response = requests.get(url, headers=headers)
print(response.text)
1.2.2 render.png 获取网页截图
# render.png获取网页截图
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36'
}
target_url = 'https://y.qq.com/n/ryqq/singer_list' # 此处不能加.html否则不会显示正常的网页截图
# #render.png 获取网页截图
url = 'http://192.168.68.242:8050/render.png?url=' + target_url + '&width=500&height=500'
response = requests.get(url, headers=headers)
with open('image.png', 'wb') as f:
f.write(response.content)
1.2.3 render.json返回请求数据
# render.json返回请求数据
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36',
'Cookie': 'pgv_pvid=3132771352; fqm_pvqid=880b3190-fa83-4efb-b454-91a8cfe5c88d; fqm_sessionid=d52acd91-a6e5-4724-b7d3-f640aa025aa9; pgv_info=ssid=s3303935717; ts_last=y.qq.com/n/ryqq/singer_list; ts_uid=5845062856; wxuin=1152921504679782202; psrf_qqopenid=; qqmusic_key=W_X_38mxV760na8eft79NlCqzAiOA-estYOQG-llR7bUbAUqZgKJXWhi-ZPtFoKHl9G0Snr-HfXYhO01O0; tmeLoginType=1; qm_keyst=W_X_38mxV760na8eft79NlCqzAiOA-estYOQG-llR7bUbAUqZgKJXWhi-ZPtFoKHl9G0Snr-HfXYhO01O0; psrf_qqunionid=; qm_keyst=W_X_38mxV760na8eft79NlCqzAiOA-estYOQG-llR7bUbAUqZgKJXWhi-ZPtFoKHl9G0Snr-HfXYhO01O0; euin=oK6kowEAoK4z7eClNKSFow-zoc**; wxopenid=opCFJwxfrEY9ZpgGrLGlFPdtA3I4; psrf_qqrefresh_token=; wxunionid=oqFLxslDReh71Tgsv2ag3if60zXM; psrf_qqaccess_token=; wxuin=1152921504679782202; wxrefresh_token=52_y1zSccbY7AxkZi958ZW7phLaZTtiNRgOyy5WbnCdYoedlU9Hn6xTTYPrWZO-lPuxFPyxX6E1t4uFGxKPkHMlAzXeXK_WS6tokw9DtYNZ9QY; login_type=2'
}
target_url = 'https://y.qq.com/portal/singer_list.html'
# render.html 获取JS加载后的网页信息
url = 'http://192.168.68.242:8050/render.json?url='+target_url+'&wait=5'
response = requests.get(url, headers= headers)
print(response.text, )
1.2.4 execute执行Lua脚本
# execute执行Lua脚本
# 因为Splash 支持Lua脚本操作
# 获取cookies
import requests
from urllib.parse import quote
# Lua脚本
luaScript = '''
function main(splash)
splash:go("https://y.qq.com/portal/singer_list")
# 返回cookies
return {
splash:get_cookies()
}
end
'''
# Lua脚本转码处理
url = 'http://192.168.68.242:8050/execute?lua_source= ' + quote(luaScript)
response = requests.get(url)
print(response.text)
从API接口的使用方法可以看到,爬取的网站是从Splash进行加载,然后再使用Requests模块对Splash发出请求,从而获取网站的网页内容。这里涉及到的API接口render.html和execute的使用频率相对较高, 特别是execute,能满足复杂点网站的多方面需求,编写Lua脚本获取网站的Cookies和设置请求头等操作。其实Splash的对象方法比较多,本人只练习了常用的对象方法。希望对您有所帮助!欢迎点赞转发。