Splash使用手册

记录了不少比较常用的splash使用语法以及场景

Splash - 使用

基础设置语法表

功能 语法
UA设置 splash:set_user_agent()
请求头设置 set_custom_headers()
查找元素 select()
查找符合条件的全部元素 select_all()
鼠标点击 mouse_click()
执行js开关 默认开启 splash.js_enabled=false
超时加载时间 默认不检测 splash.resource_timeout = 0.1 超时抛异常
代理ip request:set_proxy{host, port, username=nil, password=nil, type='HTTP'}
图片加载 splash.images_enabled=false 禁止

ua配置

语法 splash:set_user_agent()

1
2
3
4
5
6
7
function main(splash)
splash.images_enabled = false
splash:set_user_agent('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36')
splash:go('http://httpbin.org/get')
splash:wait(2)
return splash:html()
end

请求头设置

该处也可以设置 ua

1
2
3
4
5
6
7
8
9
-- 设置了请求头中的 User-Agent 和 Site 属性
function main(splash)
splash:set_custom_headers({
["User-Agent"] = "Splash",
["refare"] = "www.xxx.com",
})
splash:go("http://httpbin.org/get")
return splash:html()
end

选择器 (单个)

语法为CSS选择语法 【只返回1个值!!符合条件的第一个】

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

选择器 (全部)

语法为CSS选择语法 【只返回1个值!!符合条件的第一个】

1
2
3
4
5
6
7
8
9
10
11
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

鼠标点击

参数为坐标值 x 和 y 。此外,也可以直接选中某个节点

1
2
3
4
5
6
7
8
9
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

执行js

splash:evaljs('js语句')

1
2
3
4
5
6
7
8
function main(splash, args)
assert(splash:go('https://www.666.cq.cn'))
assert(splash:wait(0.5))
local title = splash:evaljs('document.title')
return {
{title=title}
}
end

Splash - Python - API

官方提供的API可以通过HTTP请求方式调用,注意,需要quote转化lua脚本发送

execute Demo

1
2
3
4
5
6
7
8
9
10
11
12
lua = '''
function main(splash, args)
local treat = require("treat")
local response = splash:http_get("http://httpbin.org/get")
return treat.as_string(response.body)
end
'''

url = 'http://127.0.0.1:8050/execute?lua_source=' + quote(lua)
response = requests.get(url)
ip = re.search('(\d+\.\d+\.\d+\.\d+)', response.text).group(1)
print(ip)

Splash - Scrapy

scrapy-splash 配置

安装必要模块

pip3 install scrapy-splash

scrapy中做好配置准备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
DOWNLOADER_MIDDLEWARES = {
'scrapy_splash.SplashCookiesMiddleware': 723,
'scrapy_splash.SplashMiddleware': 725,
'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
}
SPIDER_MIDDLEWARES = {
'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,
}


SPLASH_URL = 'http://localhost:8050' # 写入 splash 地址

DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter' # splash 去重类

HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage' # Chache储存配置

上图是以本机为例的配置

访问方法

1.SplashRequest

直接使用封装好的

1
2
3
4
5
6
7
yield SplashRequest(url,
self.SplashRequest,
args={
'timeout': 2,
'proxy': 'http://112.87.59.248:4216'
}
)

2.Request

和正常使用scrapy一样,在meta中配置splash参数,系统会在请求的时候自动创建一个中间件,这个中间件就是Splash

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
yield scrapy.Request(url, self.parse_result, meta={
'splash': {
# 这里设置渲染参数
'args': {
'html': 1,
'png': 1,
# 'url' 是由请求url预填的
# 对于POST请求, 'http_method'设置为'POST'
# 'body'被设置为请求POST请求的主体
},

# 可选参数
'endpoint': 'render.json', # 可选; 默认为 render.json
'splash_url': '<url>', # 可选; 重写 SPLASH_URL
'slot_policy': scrapy_splash.SlotPolicy.PER_DOMAIN,
'splash_headers': {}, # 可选; 发送给Splash的一个dict类型的headers
'dont_process_response': True, # 可选, 默认为 False
'dont_send_headers': True, # 可选, 默认为 False
'magic_response': False, # 可选, 默认为 True
}
})

代理IP

如果是服务器上的docker

用set_proxy 就会出异常,但是本地测试同一个代理ip没有问题 是因为

Splash服务器只会忽略您发送的代理身份验证标头,因此代理服务器会因验证失败而拒绝您的请求。正确的做法是让Splash发送代理身份验证标头

通俗的说就是,你通过url访问服务器,服务器接到后用你的代理信息访问了自己的docker 8050端口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
+-------------+
| Your spider |
+------+------+
|
| Proxy Authentication
v
+------+-------+
| Splash |
+------+-------+
|
|
v
+------+-------+
| Proxy server |
+------+-------+
|
|
v
+------+-------+
| Target site |
+--------------+

正确的做法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
+-------------+
| Your spider |
+------+------+
|
|
v
+------+-------+
| Splash |
+------+-------+
|
| Proxy Authentication
v
+------+-------+
| Proxy server |
+------+-------+
|
|
v
+------+-------+
| Target site |
+--------------+

set_proxy指定代理ip

注意,该方法只支持 HTTP 和 SOCKS5 并且 不支持异步操作
当type设置为’HTTP’时,HTTPS代理也应该起作用; 它是使用CONNECT命令实现的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function main(splash, args)
splash:on_request(function(request)
request:set_proxy{
host = '112.87.59.248',
port = 4216,
username = '',
password = '',
type = "HTTP",
}
end)
splash:go('http://httpbin.org/get')

return {
html = splash:html(),
png = splash:png(),
}
end

如果不需要 username 和 password 就不填,type默认值就是HTTP

docker中配置共享代理文件

  1. 现在宿主机上创建一个 xxx.ini 的文件
  2. 文件内容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    [proxy]

    host=代理ip
    port=端口

    ; 可选,默认值不是auth
    username=username
    password=password

    ; 可选,默认是HTTP。允许的值是HTTP和SOCKS5
    type=HTTP

    [rules]
    ; 可选的,默认“。*”
    whitelist=
    .*mywebsite\.com.*

    ; 可选,默认没有黑名单
    blacklist=
    .*\.js.*
    .*\.css.*
    .*\.png
  1. 在启动docker时共享xxx.ini所在目录

    1
    $ docker run -p 8050:8050 -v /root:/etc/splash/proxy-profiles scrapinghub/splash
  2. 如果 配置文件名设置为 default.ini 那么将会在请求时自动带上代理IP

  3. 否则启动方法 在lua脚本中加上 proxy=xxx.ini