爬虫主流框架分享--Scrapy【第七期】
文章主讲内容:基于Scrapy框架的分布式爬虫实现原理【最后一期】
分布式爬虫的原理及基于scrapy怎么实现分布式爬虫
分布式爬虫的原理
分布式爬虫目的:多台服务器抓取一个爬虫项目,数据不重复,提高数据抓取速度和效率!
原理:多台服务器共享一个 url 队列(redis集合),然后一起进行数据的抓取
原理实现图:
注意:多台服务器共享爬取队列是通过 scrapy_redis 模块创建的 redis 集合
你问我答:三台服务器都部署相同的爬虫项目,也就拥有相同数量的的爬虫url地址(假设500),当三台服务器将所有的url都经过自身调度器交给redis创建的集合(全局url队列)之后,集合里面有多少个url地址呢?
答:有500个url地址,因为redis的集合有去重功能,三个相同的爬虫项目,那每台服务器上面的url都是一样的啊
内部流程图:
注意:
1:当url通过自身调度器进入到redis创建的集合中之后,redis会为这个url生成一个指纹(实现增量式爬虫以及url的去重机制)
2:自身调度器将url从redis集合中取出来之后,全局url队列会记录哪台服务器取走了哪个url地址,这样多台服务器协同工作时就不会出现取走相同的url并且下载的情况,也就实现了分布式!
3:假如公司有四台服务器,做分布式爬虫时,一般需要一台服务器进行url地址的管理!!
4:负责管理url地址的那台服务器也可以进行数据的抓取!!!
实现分布式爬虫:
实现原理:因为 scrapy 自身的调度器不支持分布式爬虫,因此我们需要重写 scrapy 框架的调度器从而实现分布式爬虫
具体实现:
1:安装 scrapy_redis模块(用作分布式爬虫的 url 全局共享队列)→ 也就是重写scrapy的调度器
安装指令:
1 | sudo pip3 install scrapy_redis |
须知:为什么要用redis的集合充当分布式爬虫的全局url共享队列呢?
答:因为redis是基于内存存储的,url的进与出较快,另一个原因就是 redis的集合有去重功能
2:创建非分布式的 scrapy 爬虫
3:在 settings.py 文件内设置一些参数即可
4:多台服务器同时运行一个爬虫项目实现分布式
创建分布式爬虫的具体步骤
第一步:按照非分布式爬虫的流程创建scrapy爬虫
第二步:在settings.py文件内进行参数设置,将非分布式爬虫设置为分布式爬虫(具体参数设置看下面)
第三步:在多台服务器上面同时运行相同的爬虫文件
分布式爬虫在settings.py文件内怎么设置参数
参数设置:
重新指定调度器(重写调度器):
1 | SCHEDULER = "scrapy_redis.scheduler.Scheduler" |
重新指定去重机制:
1 | DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" |
是否清除url指纹(默认False是清除):
1 | SCHEDULER_PERSIST = True |
解释:爬虫项目结束之后,是否将url指纹清空,不清空将url指纹存在redis数据库内
这个参数很重要常常用作爬虫的暂停、回复、断点续爬,最重要是可以实现增量式爬虫!!!
设置 redis 管道:ITEM_PIPELINES = { ‘scrapy_redis.pipelines.RedisPipeline’: 优先级系数,}
解释:如果需要将爬取的数据存入到redis数据库内就直接设置这个项目管道即可存入,不存redis就不用设置
指定当前服务器连接到哪台服务器上面的redis数据库(连接充当url地址管理的那台服务器上面的redis):
REDIS_HOST = “IP地址” 【充当 url 地址管理的那台服务器的IP地址】
REDIS_PORT = 端口号 【redis 端口号是 6379】
如果 redis 设置了密码就这样设置: REDIS_URL = “redis://user:密码@用户名:PORT”
RedisDesktopManager的使用
RedisDesktopManager 怎么连接 redis 数据库
RedisDesktopManager 怎么刷新 redis 数据库里面的数据
RedisDesktopManager 怎么查看数据库里面的数据等操作
分布式爬虫的实现【实操】
实现分布式爬虫前的准备
1:准备多台服务器【每台服务器上都安装了 redis数据库以及 scrapy 框架】
2:确保多台服务器都可以远程连接 url 地址管理的那台服务器的 redis 数据库
3:在任意一台服务器上可安装 RedisDesktopManager 图形化远程查看 redis 数据库内数据的变化
怎么远程连接 redis 数据库
安装前注意事项:待连接数据库主机以及连接数据库主机上面都需要安装 redis 数据库
远程连接指令:
1 | redis-cli -h 待连接 redis 数据库的 IP 地址 |
图示:
怎么解决服务器不能远程连接另外一台服务器的 redis 数据库
第一步:在待远程链接的服务器(ubuntu)上面打开 /etc/redis/redis.conf 这个文件【在主目录下打开】
第二步:将 bind 127.0.0.1这段代码注释
第三步:将保护模式关闭
第四步:重启 redis 服务
第五步:重新远程连接 redis 数据库
创建分布式爬虫的步骤
第一步:利用 scrapy 创建非分布式爬虫
第二步:更改 settings.py 文件内的数据将非分布式爬虫部署为分布式爬虫
第三步:将 scrapy 写好的爬虫项目复制到其他几台服务器上面(其他几台服务器必须都安装 scrapy 框架以及 redis 数据库和 scrapy_redis)
注意:多台服务器上面还要保证 python 的版本都要一致
第四步:其他几台服务器一起【同时】运行这个爬虫项目即可实现分布式
Ubuntu系统运行爬虫项目:
其他服务器【win】运行分布式爬虫文件
第一步:进入爬虫项目文件夹
第二步:进入爬虫项目文件夹后进入终端
第三步:输入指令运行爬虫文件
注意:多台服务器实现分布式爬虫每台服务器都需要安装 redis 数据库
当分布式爬虫运行 充当 url 地址管理的那台服务器上面的 redis 数据库内都存放了什么数据!
1:数据存放在了那里?
答:redis 数据库默认将数据存放至代号为 db0 那个数据库里面
2:db0 数据库里面都存放了哪些数据?
答:存放了 url 地址指纹、以及爬取的数据
如何实现分布式增量式爬虫
实现原理:在分布式爬虫程序结束之后,不清除 url 指纹,下载再次运行这个分布式爬虫即可实现增量式爬虫
不清除指纹设置:在 settings.py 文件内设置 SCHEDULER_PERSIST 的参数值为 True 即不清除 url 指纹
运行分布式爬虫出现的问题解决
出现的问题:在多台服务器同时运行同一个爬虫项目,因为 python 版本的不同会出现 builtins.ValueError 这种错误!
问题解决:将所有爬虫服务器上面的 python 版本都设为一致【具体操作请看 python 怎么卸载和升级】
redis_key部署分布式爬虫
redis_key 部署分布式爬虫与上面正常部署分布式爬虫相比有哪些不同?
不同点:正常分布式爬虫多台主机同时运行后就开始数据的抓取了,redis_key 部署的分布式爬虫多台主机同时运行后不开始数据的抓取而是同时监听 6023 端口 等待在 redis 数据库命令行内压入初始 url 地址多台主机才同时进行数据的抓取,这样更好的控制多台主机的同步性
redis_key 部署分布式爬虫的具体步骤
第一步:正常创建一个分布式爬虫【非分布式爬虫 → 设置 settings.py文件变成分布式爬虫】
第二步:在真的爬虫文件内导入 RdeisSpider 类,并且真的爬虫类继承这个类后,注释掉 start_urls 这段代码并设置 redis_key 的参数值
导入模块语法:
1 | from scrapy_redis.spiders import RedisSpider |
第三步:多台服务器同时运行部署的分布式爬虫
windows服务器运行redis_key创建好的爬虫
ubuntu服务器运行redis_key创建好的爬虫
第四步:进入充当 url 地址管理的那台服务器的 redis 数据库内【命令行】并压入初始 url 地址实现多台主机同时抓取数据
压入初始 url 指令:LPUSH 设置的redis_key值 初始的url地址
注意:初始 url 地址就是注释的 start_urls 的 url 值
redis_key 部署分布式爬虫的缺点以及怎么解决这个缺点
缺点:redis_key 部署的分布式爬虫在数据抓取结束后程序不会终止
解决办法:在 settings.py 文件内设置 CLOSESPIDER_TIMEOUT = 3600 【到了3600时间后程序会自动退出】
持续更新中……