python爬虫-scrapy-redis分布式

时间:2022-06-12 20:20:01
'''
10.scrapy-redis分布式组件
分布式:多台机器协同完成,提高效率缩短时间
scrapy-redis组件和普通scrapy的区别:
(1)引擎和下载器没变化
(2)每个分布式的爬虫是共同完成一个任务,每个爬虫的调度器和redis数据库相连,redis中有对url的去重和 url的队列,
start_url是随机分配给一个爬虫文件开始执行,然后响应中新解析出来的url通过调度器放到redis中去重保存到url队列中,然后
哪个爬虫的下载器空闲,就会分配给它执行,即原来scrapy调度器的功能放到redis中
(3)每个爬虫都有itempipeline保存模块,不能重复保存啊,所以处理过的数据需要接下来保存的,也放到redis中分别把保存任务分配给每个爬虫
(4) 即redis中 任务队列(url)(去重) 和 数据队列(用于pipeline保存)
(5) 特性:爬虫中断,恢复时会继续进行
'''




'''
11.scrapy 改成 scrapy-redis
pip install scrapy-redis
setting中5条:
(1)过滤器 : DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
(2)调度器 : SCHEDULER = "scrapy_redis.scheduler.Scheduler"
(3)中断保持任务队列 : SCHEDULER_PERSIST = True            实现断点续传
(4)管道注册中 : 'scrapy_redis.pipelines.RedisPipeline': 数字
(5)redis链接信息 : REDIS_URL = 'redis://127.0.0.1:6379'


spider模块:
开了分布式爬虫,是几个爬虫文件同时运行起来,都等待redis分配起始的url,只有同时都开启来了才能叫分布式啊,
开启并等待 scrapy runspider 爬虫名
链接redis,并插入起始url, 格式 lpush 键:redis_key的值  值:目标url
spider中4条:
(1)继承类 RedisSpider 或者 RedisCrawlSpider
(2)注销 允许的域 和 起始url (动态在init方法中获取)
(3)添加 redis_key = 'myspider(什么什么随便写一般同文件名)'
(4)重写init方法:
    def __init__(self, *args, **kwargs):
        domain = kwargs.pop('domain', '')
        self.allowed_domains = list(filter(None, domain.split(',')))
        super(类名, self).__init__(*args, **kwargs)   继承父类的方法
'''




'''
12.数据持久化
将redis中储存的数据放入其他持久储存的数据库中
# 链接数据库
cli = redis.Redis(host='127.0.0.1',port=6379, db=0)
mongo_cli = MongoClient('127.0.0.1',27017)
db = mongo_cli['DMOZ']
col = db['dmoz']


while True:
    # 从redis中读取 是键值对的格式 用key把value拿出来,拆包 
    key, value = cli.blpop(['key'])


    # 写入到mongodb中,redis中拿出来的是byte类型,需要转换
    dict_data = json.loads(data)
    col.insert(dict_data)
'''




'''
13.scrapy使用selenium原因(selenium的响应中带有渲染过的完整json数据)
scrapy无法对js发出请求,我们指定了起始url和提取响应中的url,如果其中的数据是js动态请求回来的,那scrapy无法获取
用法:写在下载器中间件中(效率很低)
from scrapy.http import HtmlResponse
class SeleniumMiddleware(object):
    # 下载器中间件全局掌控所有请求和响应,但是我们需要设置成只对需要js请求数据的url进行自主操作
    def process_request(self, request, spider):
        # process_request 处理请求
        # 过滤需要动态加载的url
        url = request.url
        if 'daydata' in url:    如果daydata在请求的地址中说明是获取当月每天的空气质量
            driver = webdriver.Chrome()    建议无头浏览器


            driver.get(url)
            time.sleep(3)     必须延时,因为selenium自动化需要时间加载js请求


            data = driver.page_source   page_source方法获取的就是带有json数据渲染过的网页,因为我们是操作浏览器,得到的页面就是有完整数据的


            driver.close()


            # 构建响应,并将响应返回      需要我们构建响应,这些过滤的url就不走下载器了
            res = HtmlResponse(
                url=url,         响应对应的url
                request=request,    响应对应的请求
                encoding='utf-8',   编码格式
                body=data          渲染过的完整页面在body参数
            )
            return res
'''




'''
14.scrapy的远程监控
安装scrapyd:  开了一个服务器,把爬虫项目配置进去,运行爬虫,实施监控
pip3 install scrapyd
pip3 install scrapyd-client


启动scrapyd服务: sudo scrapyd (在127.0.0.1:6800)


配置爬虫文件: scrapy.cfg文件
[deploy:部署名]
url = http://localhost:6800/
project = 项目名


部署项目到scrapyd:
scrapyd-deploy  部署名称 -p  项目名称

启动爬虫:
curl  http://localhost:6800/schedule.json -d project=project_name -d spider=spider_name

关闭爬虫
curl http://localhost:6800/cancel.json -d project=project_name -d job=jobid




'''




'''
15.远程操作爬虫模块


进入远程控制:
telnet ip 6023
对任务的操作:
engine.pause() 暂停运行引擎
engine.unpause() 继续运行引擎
engine.stop() 停止引擎


引擎运行状态查询:
est()


检查内存状态:
prefs()