分布式爬虫框架服务
提供用于 https://github.com/zly-app/zapp 的服务
说明
crawler.WithService()#启用服务crawler.RegistrySpider(...)#服务注入spider
示例
packagemainimport("fmt""github.com/zly-app/zapp""github.com/zly-app/crawler""github.com/zly-app/crawler/core")//一个spidertypeSpiderstruct{core.ISpiderTool//必须继承这个接口}//初始化func(s*Spider)Init()error{returnnil}//提交初始化种子func(s*Spider)SubmitInitialSeed()error{seed:=s.NewSeed("https://www.baidu.com/",s.Parser)//创建种子并指定解析方法s.SubmitSeed(seed)//提交种子returnnil}//解析方法func(s*Spider)Parser(seed*core.Seed)error{fmt.Println(string(seed.HttpResponseBody))//打印响应bodyreturnnil}//关闭func(s*Spider)Close()error{returnnil}funcmain(){app:=zapp.NewApp("a_spider",crawler.WithService())//启用crawler服务crawler.RegistrySpider(new(Spider))//注入spiderapp.Run()//运行}
配置
不需要任何配置文件就可以运行
默认服务类型为 crawler
, 完整配置说明参考 Config
配置参考
#爬虫配置[services.crawler.spider]#爬虫名Name='a_spider'#提交初始化种子的时机SubmitInitialSeedOpportunity='start'#是否自动管理cookieAutoCookie=false#框架配置[services.crawler.frame]#请求超时,毫秒RequestTimeout=20000#最大尝试请求次数RequestMaxAttemptCount=5
持久化队列
使用redis作为队列
[services.crawler.queue]type='redis'#使用redis作为队列,默认是memoryAddress='127.0.0.1:6379'#地址UserName=''#用户名,可选Password=''#密码,可选DB=0#db,只有非集群有效,可选,默认0IsCluster=false#是否为集群,可选,默认falseMinIdleConns=1#最小空闲连接数,可选,默认1PoolSize=1#客户端池大小,可选,默认1ReadTimeout=5000#读取超时(毫秒,可选,默认5000WriteTimeout=5000#写入超时(毫秒,可选,默认5000DialTimeout=5000#连接超时(毫秒,可选,默认5000
使用ssdb作为队列
[services.crawler.queue]type='ssdb'#使用ssdb作为队列,默认是memoryAddress='127.0.0.1:8888'#地址Password=''#密码,可选MinIdleConns=1#最小空闲连接数,可选,默认1PoolSize=1#客户端池大小,可选,默认1ReadTimeout=5000#读取超时(毫秒,可选,默认5000WriteTimeout=5000#写入超时(毫秒,可选,默认5000DialTimeout=5000#连接超时(毫秒,可选,默认5000
使用持久化集合
没错, 和队列的配置内容相似
使用redis作为集合
[services.crawler.set]type='redis'#使用redis作为队列,默认是memoryAddress='127.0.0.1:6379'#地址UserName=''#用户名,可选Password=''#密码,可选DB=0#db,只有非集群有效,可选,默认0IsCluster=false#是否为集群,可选,默认falseMinIdleConns=1#最小空闲连接数,可选,默认1PoolSize=1#客户端池大小,可选,默认1ReadTimeout=5000#读取超时(毫秒,可选,默认5000WriteTimeout=5000#写入超时(毫秒,可选,默认5000DialTimeout=5000#连接超时(毫秒,可选,默认5000
使用ssdb作为集合
[services.crawler.set]type='ssdb'#使用ssdb作为队列,默认是memoryAddress='127.0.0.1:8888'#地址Password=''#密码,可选MinIdleConns=1#最小空闲连接数,可选,默认1PoolSize=1#客户端池大小,可选,默认1ReadTimeout=5000#读取超时(毫秒,可选,默认5000WriteTimeout=5000#写入超时(毫秒,可选,默认5000DialTimeout=5000#连接超时(毫秒,可选,默认5000
使用代理
[services.crawler.proxy]type='static'#静态代理,支持http,https,socks5,socks5haddress='socks5://127.0.0.1:1080'#代理地址User=''#用户名,可选Password=''#密码,可选
概念
种子 seed
描述你要下载数据的站点
这个站点如何请求, 请求的表单和body是什么, cookie?, 是否自动跳转, 失败如何重试等
数据拿到后怎么处理
数据在什么时候抓, 数据每隔多久抓一次
这就是seed
, seed
描述了一个数据从开始抓取到处理的过程
seed
是无状态的
队列 queue
我们待抓取的seed
会存放到队列中, 依次从队列前面拿出一个seed
开始抓取流程.
如果抓取的数据是一个列表, 如文章列表, 处理程序应该依次遍历并提交包含了文章信息的seed
这些seed
将根据配置放到队列的前面或后面, 然后继续开始下一轮抓取.
队列是框架实现分布式, 并行化, 无状态化的基础.
下载器 downloader
使用go内置库http
进行请求
下载器会根据seed
描述自动构建请求请求体, 请求方法, 请求表单, header, cookie等
中间件 downloader
中间件包括请求中间件
和响应中间件
请求中间件
的职责是在downloader
处理seed
之前检查seed
的合法性或者判断是否应该请求.
响应中间件
的职责是在downloader
处理seed
之后检查数据的合法性或者判断是否应该将seed
交给处理程序
开发者可以开发自己的中间件
设计思路
进程独立
在crawler
的基础设计里, 爬虫运行的最小单元为一个进程, 一个爬虫可能有多进程, 每个进程可以在任何机器上运行.
每个进程同一时间只会处理一个seed
, 每个进程具有独立的db连接, 独立的downloader
等, 进程之间互不影响.
你无需关心多进程之间是怎么协调的, 在开发的时候按照单进程开发然后运行时启动多个进程就行了.
多进程需要队列服务支持, 比如redis
, ssdb
. 使用memory
队列开启多进程运行爬虫可能产生意外的结果.
请求独立
每个请求都是独立的, seed
与进程隔离, 进程通过消耗初始种子(初始url)根据处理逻辑生成更多的种子并放入队列, 进程再从队列取出种子你进行请求和解析.
重复的从队列中取出种子处理并保存数据并生成种子放入队列, 直到队列中没有种子为止.
抓取过程
seed
在请求前会经过请求中间件
进行检查.
下载器downloader
会根据seed
自动将网站数据下载并写入seed
中.
下载完成后seed
会经过响应中间件
进行检查.
将seed
交给处理程序, 使用者决定如何对数据进行抽取.
注: 种子抓取过程中如果收到结束信号会将种子放回队列防止种子丢失
配置化
在设计上, 尽力将开发中可能存在改变的常量抽离出来形成配置文件, 方便后期调整.
模块化
将爬虫的请求, 队列, 代理, 下载器, 配置管理等抽象为单独的模块, 各司其职, 得以解耦合, 方便后期升级维护
使用者也可以根据自己的需求重新设计自己的逻辑替换一些模块.
进程管理
开发中...
一些操作
这条数据我已经抓过了, 怎么让爬虫不再抓它了
将处理完毕(想要拿到的数据已经持久化)的seed
的唯一标志(一般是url)存入集合.
提交新的seed
之前检查集合中是否已存在这个唯一标志, 就这么简单
注: 这种方式仍然可能会再次抓取相同的数据, 因为你可能在这个seed
处理完毕之前又提交了相同唯一标志的seed
非请求的seed
一个seed
可能不需要请求, 但是seed
必须要有处理程序
工程管理工具
安装 go install github.com/zly-app/crawler/tools/crawler@latest
使用说明 crawler help
命令
初始化一个项目 crawler init <project_name> && cd <project_name>
创建一个爬虫 crawler create <spider>
提交初始化种子 crawler start <spider>
清空爬虫所有队列 crawler clean <spider>
清空爬虫集合数据 crawler clean_set <spider>
生成 supervisor
配置, 点 这里 进入supervisor官网
crawler make
会根据文件 configs/supervisor_programs.toml
在 supervisor_config/conf.d
目录下生成一些 ini
文件
将 supervisor
的配置修改包含文件 <project_dir>/supervisor_config/conf.d/*.ini
调度器工具
安装 go build github.com/zly-app/crawler/tools/crawler_scheduler
将 supervisor
的配置修改包含以下文件 <project_dir>/supervisor_config/scheduler_config.ini