Scrapy-Splash-爬虫
本文最后更新于:2021年2月5日 晚上
信息
Scrapy的Splash插件
github地址:https://github.com/scrapy-plugins/scrapy-splash
这个插件只是让Scrapy使用Splash服务而已
如果没人给你提供Splash服务,那么你需要自己弄
流程
安装
pip install scrapy-splash
配置
在
settings.py
中添加Splash
地址1
SPLASH_URL = 'http://192.168.59.103:8050'
根据ip来,要是本地就localhost:8050
在
settings.py
中配置Downloader
中间件1
2
3
4DOWNLOADER_MIDDLEWARES = {
'scrapy_splash.SplashCookiesMiddleware': 723,
'scrapy_splash.SplashMiddleware': 725, 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
}启用Spider中间件
SplashDeduplicateArgsMiddleware
1
2
3SPIDER_MIDDLEWARES = {
'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,
}这个功能需要
cache_args
支持。
它能通过不保存 重复的Splash参数 节约磁盘空间
若Splash版本2.1+,它能通过 不重复发送Splash参数 节约带宽设置去重类
DUPEFILTER_CLASS
1
DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'
如果你使用HTTP cache,那么要定义一个缓存后端
scrapy-splash提供一个
scrapy.contrib.httpcache.FilesystemCacheStorage
子类1
HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'
使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17yield SplashRequest(url, self.parse_result, callback #任务完成之后对应的回调函数
#args设置的是端点API的参数,关于API参数问题,请参考: `Splash HTTP API <./api.html>`_
args={
# 可选参数,表示spalsh在执行完成之后会等待一段时间后返回
'wait': 0.5,
#url是一个必须的参数,表明将要对哪个url进行请求
'url' : "http://www.example.com",
#http_method:表示Splash将向目标url发送何种请求
'http_method': 'GET'
# 'body' 用于POST请求,作为请求的请求体
# 'lua_source' 如果需要执行lua脚本,那么这个参数表示对应lua脚本的字符串
},
endpoint='render.json', # optional; default is render.html
splash_url='<url>', # optional; overrides SPLASH_URL
slot_policy=scrapy_splash.SlotPolicy.PER_DOMAIN, # optional,
# "meta" 是一个用来向回调函数传入参数的方式,在回调函数中的response.meta中可以取到这个地方传入的参数
)如果在splash中使用lua脚本,那么args中的内容会通过main函数的 splash.args 参数传入,其余的内容会通过第二个 参数 args 传入。
比如下面有一个简单的用户登录的例子:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36lua_script= '''
function main(splash, args)
local ok, reason = splash:go(args.url)
user_name = args.user_name
user_passwd = args.user_passwd
user_text = splash:select("#email")
pass_text = splash:select("#pass")
login_btn = splash:select("#loginbutton")
if (user_text and pass_text and login_btn) then
user_text:send_text(user_name)
pass_text:send_text(user_passwd)
login_btn:mouse_click({})
end
splash:wait(math.random(5, 10))
return {
url = splash:url(),
cookies = splash:get_cookies(),
headers = splash.args.headers,
}
end'''
yield SplashRequest(
url=self.login_url,
endpoint="execute",
args={
"wait": 30,
"lua_source": lua_script,
"user_name": "xxxx", # 在Lua脚本中这个参数可用通过args.user_name取得
"user_passwd": "xxxx",
},
meta = {"user_name" : "xxxx"},
callback=self.after_login,
errback=self.error_parse,
)上述代码提交了一个Splash的请求,在脚本中首先获取用户名和密码的输入框元素和对应的提交按钮元素,接着填入用户名和 密码,最后点击提交并返回对应的cookie。 回调函数 after_login 的代码如下:
1 |
|
在回调函数中,可以通过response.data
来获取lua
脚本中返回的内容,而对应的HTML代码的获取方式与使用传统的Request
方式 相同。
另外在回调函数中可以通过response.meta
来获取Request
中meta
传入的参数。
上述示例演示了如何使用SplashRequest
来像Splash
发送渲染请求,以及如何在回调函数中获取lua脚本中的返回、 以及如何在回调函数中获取lua脚本中的返回、如何向回调函数传递参数。
当然您也可以使用常规的scrapy.Request
来向Splash
发送请求,发送的示例如下:
1 |
|
splash 参数中的内容是用于splash的,使用这个参数表明我们希望向splash发送渲染请求。
最终它们会被组织成 request.meta[‘splash’] 。在scrapy处理这些请求的时候根据这个来确定是否创建spalsh的 中间件,最终请求会被中间件以HTTP API的方式转发到splash中
splash
中各个参数的作用如下:
meta[‘splash’][‘args’] 是最终发送到splash HTTP API的参数
- url 表示目标站点的url
- http_method 表示向url发送的HTTP的请求方式
- body 是采用POST方式发送请求时,请求体的内容
meta[‘splash’][‘cache_args’] 表示将要被作为缓冲的参数的列表字符串,以分号分隔
meta[‘splash’][‘endpoint’] 表示对应的端点
meta[‘splash’][‘splash_url’] 与settings文件中的 SPLASH_URL 作用相同,但是会优先采用这里的设置
meta[‘splash’][‘splash_headers’] 即将发送到splash服务器上的请求头信息,注意,这里它不是最终发送到对应站点的请求头信息
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!