大家好,欢迎来到IT知识分享网。
一、splash的介绍
Splash是一个JavaScript渲染服务,是一个带有HTTP API的轻量级浏览器,同时它对接了Python中的Twisted和QT库。利用它,我们同样可以实现动态渲染页面的抓取
二、splash的安装
1、docker 安装
参考:Dockerapp安装与使用_宠乖仪的博客-CSDN博客_docker安装使用
2、拉取镜像
docker pull scrapinghub/splash
等待安装即可
3、用docker运行scrapinghub/splash
docker run -p 8050:8050 scrapinghub/splash
4、查看效果
三、Splash对象属性
上图中main()方法的第一个参数是splash,这个对象非常重要,它类似于Selenium中的WebDriver对象
1、scroll_position
控制页面上下或左右滚动
splash.scroll_position = {x=100, y=200}
四、Splash对象的方法
1、go()
该方法用来请求某个链接,而且它可以模拟GET和POST请求,同时支持传入请求头、表单等数据
ok, reason = splash:go{url, baseurl=nil, headers=nil, http_method="GET", body=nil, formdata=nil}
> 返回结果是结果ok和原因reason
> 如果ok为空,代表网页加载出现了错误,此时reason变量中包含了错误的原因
参数 | 含义 |
---|---|
url | 请求的URL |
baseurl | 可选参数,默认为空,表示资源加载相对路径 |
headers | 可选参数,默认为空,表示请求头 |
http_method | 可选参数,默认为GET,同时支持POST |
body | 可选参数,默认为空,发POST请求时的表单数据,使用的Content-type为application/json |
formdata | 可选参数,默认为空,POST的时候的表单数据,使用的Content-type为application/x-www-form-urlencoded |
2、wait()
控制页面的等待时间
splash:wait{time, cancel_on_redirect=false, cancel_on_error=true}
参数 | 含义 |
---|---|
time | 等待的秒数 |
cancel_on_redirect | 可选参数,默认为false,表示如果发生了重定向就停止等待,并返回重定向结果 |
cancel_on_error | 可选参数,默认为false,表示如果发生了加载错误,就停止等待 |
function main(splash)
splash:go("https://www.taobao.com")
splash:wait(2)
return {html=splash:html()}
end
3、jsfunc()
直接调用JavaScript定义的方法,但是所调用的方法需要用双中括号包围,这相当于实现了JavaScript方法到Lua脚本的转换
function main(splash, args)
splash:go("http://www.baidu.com")
local scroll_to = splash:jsfunc("window.scrollTo")
scroll_to(0, 300)
return {png=splash:png()}
end
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(args.url)
return ("There are %s DIVs in %s"):format(
get_div_count(), args.url)
end
4 、evaljs()与 runjs()
-
evaljs() 以执行JavaScript代码并返回最后一条JavaScript语句的返回结果
-
runjs() 以执行JavaScript代码,它与evaljs()的功能类似,但是更偏向于执行某些动作或声明某些方法
function main(splash, args)
splash:go("https://www.baidu.com")
splash:runjs("foo = function() { return 'sxt' }")
local result = splash:evaljs("foo()")
return result
end
5、 html()
获取网页的源代码
function main(splash, args)
splash:go("https://www.baidu.com")
return splash:html()
end
6、png()
获取PNG格式的网页截图
function main(splash, args)
splash:go("https://www.baidu.com")
return splash:png()
end
7、har()
获取页面加载过程描述
function main(splash, args)
splash:go("https://www.baidu.com")
return splash:har()
end
8、url()
获取当前正在访问的URL
function main(splash, args)
splash:go("https://www.baidu.com")
return splash:url()
end
9、get_cookies()
获取当前页面的Cookies
function main(splash, args)
splash:go("https://www.baidu.com")
return splash:get_cookies()
end
10、add_cookie()
当前页面添加Cookie
cookies = splash:add_cookie{name, value, path=nil, domain=nil, expires=nil, httpOnly=nil, secure=nil}
function main(splash)
splash:add_cookie{"sessionid", "123456abcdef", "/", domain="http://bjsxt.com"}
splash:go("http://baidu.com/")
return splash:html()
end
11、 clear_cookies()
# 可以清除所有的Cookies
function main(splash)
splash:go("https://www.bjsxt.com/")
splash:clear_cookies()
return splash:get_cookies()
end
12、set_user_agent()
设置浏览器的User-Agent
function main(splash)
splash:set_user_agent('Splash')
splash:go("http://httpbin.org/get")
return splash:html()
end
13、set_custom_headers()
设置请求头
function main(splash)
splash:set_custom_headers({
["User-Agent"] = "Splash",
["Site"] = "Splash",
})
splash:go("http://httpbin.org/get")
return splash:html()
end
14、 select()
选中符合条件的第一个节点
如果有多个节点符合条件,则只会返回一个
其参数是CSS选择器
function main(splash)
splash:go("https://www.baidu.com/")
input = splash:select("#kw")
splash:wait(3)
return splash:png()
end
15、send_text()
填写文本
function main(splash)
splash:go("https://www.baidu.com/")
input = splash:select("#kw")
input:send_text('Splash')
splash:wait(3)
return splash:png()
end
16、mouse_click()
模拟鼠标点击操作
function main(splash)
splash:go("https://www.baidu.com/")
input = splash:select("#kw")
input:send_text('Splash')
submit = splash:select('#su')
submit:mouse_click()
splash:wait(3)
return splash:png()
end
17、代理Ip
function main(splash)
splash:on_request(function(request)
request:set_proxy{
host='111.111.111.1',
port=8080,
username='uanme',
password='passwrod'
}
end)
-- 设置请求头
splash:set_user_agent("Mozilla/5.0")
splash:go("https://httpbin.org/get")
return splash:html()
end
五、splash与python结合
1、render.html
此接口用于获取JavaScript渲染的页面的HTML代码,接口地址就是Splash的运行地址加此接口名称,例如http://127.0.0.1:8050/render.html
url = 'https://www.lagou.com/zhaopin/Python/'
base_url =f'http://localhost:8050/render.html?url={url}&wait=2'
resp = requests.get(base_url)
resp.encoding = 'utf-8'
print(resp.text)
2、render.png
此接口可以获取网页截图
url = 'https://www.lagou.com/zhaopin/Python/'
base_url =f'http://localhost:8050/render.png?url={url}&wait=2'
resp = requests.get(base_url)
with open('a.png','wb') as f:
f.write(resp.content)
3、 execute
最为强大的接口。前面说了很多Splash Lua脚本的操作,用此接口便可实现与Lua脚本的对接
url = 'https://www.lagou.com/zhaopin/Python/'
lua =f'''
function main(splash,args)
splash:go("{url}")
splash:wait(2)
return splash:html()
end
'''
base_url =f'http://localhost:8050/execute?lua_source={lua}'
resp = requests.get(base_url)
print(resp.text)
# 如果lua代码中有特殊字符,要通过进行quote转码
from urllib.parse import quote
url = 'https://www.baidu.com'
lua =f'''
function main(splash,args)
splash:go("{url}")
input = splash:select("#kw")
input : send_text("SXT")
splash:wait(0.1)
button = splash:select("#su")
button : mouse_click()
splash : wait(2)
return splash:html()
end
'''
base_url =f'http://localhost:8050/execute?lua_source={quote(lua)}'
resp = requests.get(base_url)
print(resp.text)
六、scrapy与splash结合
1、pip安装scrapy-splash库
pip install scrapy-splash
2、scrapy-splash使用的是Splash HTTP API, 所以使用之前要开启splash
3、配置splash服务(以下操作全部在settings.py):
3.1 使用splash解析,要在配置文件中设置splash服务器地址:
SPLASH_URL = 'http://localhost:8050/'
3.2 将splash middleware添加到DOWNLOADER_MIDDLEWARE中
DOWNLOADER_MIDDLEWARES = {
'scrapy_splash.SplashCookiesMiddleware': 723,
'scrapy_splash.SplashMiddleware': 725,
'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
}
3.3 Enable SplashDeduplicateArgsMiddleware
SPIDER_MIDDLEWARES = {
'scrapy_splash.SplashDeduplicateArgsMiddleware': 100
}
这个中间件需要支持cache_args功能; 它允许通过不在磁盘请求队列中多次存储重复的Splash参数来节省磁盘空间。如果使用Splash 2.1+,则中间件也可以通过不将这些重复的参数多次发送到Splash服务器来节省网络流量
3.4 配置消息队列所使用的过滤类
DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'
3.5 配置消息队列需要使用的类
HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'
案例
import scrapy
from scrapy_splash import SplashRequest
class DoubanSpider(scrapy.Spider):
name = 'douban'
allowed_domains = ['douban.com']
def start_requests(self):
yield SplashRequest('https://movie.douban.com/typerank?type_name=剧情&type=11&interval_id=100:90', args={'wait': 0.5})
def parse(self, response):
print(response.text)
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/11052.html