• 去重


    去重原理:
    相当于是写了集合self.vister_urls=set(),把所有的url放进去当执行yield Requets的时候就会执行,进行判断,看是否这个访问的url在这个集合里面,如果在的话,就不添加进去了

    from scrapy.utils.request import request_fingerprint##进行加密,url的唯一标识

    每一次yield Request的时候,就会执行settings里面的去重
    从from_settings开始执行,返回的时候,就执行下面的requets_seen方法

    settings:
    #执行自定义的去重规则
    DUPEFILTER_CLASS='scrapyproject1.dupliter.Self_Dupliter'

    spider:

    #yield   Request(url=page_url, callback=self.parse,dont_filter=True)##每一次requets的时候,就会执行去重的方法,不准询去重规则,如果要遵循的话,那么应该为false
    要遵循去重规则,就要改成dont_filter=False,或者不添加,默认为False

    原理分析:

    from   scrapy.dupefilter import  BaseDupeFilter
    from scrapy.utils.request import request_fingerprint##进行加密,url的唯一标识,会进行加密处理
    '''
    在scrapy里面有一个唯一标识
    http://xxx.com/?k1=v1&k2=v2
    http://xxx.com/?k2=v2&k1=v1
    如果是md5进行加密的话,这两个url是不一样的,但是这两个url是相同的
    但是scrapy里面有一个方法,可以辨别出两个相同的url出来
    request_fingerprint(放在里面进行加密,如果是相同的打印出来也是相同的)
    '''

    ##去重

    class Self_Dupliter(BaseDupeFilter):
    def __init__(self):
    self.vister_urls=set()
    ##设置url元祖


    @classmethod
    def from_settings(cls, settings):
    print('最开始')
    return cls()

    # def request_seen(self, request):###传入的requets里面有url,可以直接取出来
    # print('执行去重规则')
    # if request.url in self.vister_urls:
    # return True
    # self.vister_urls.add(request.url)
    # return False

    def request_seen(self, request): ###传入的requets里面有url,可以直接取出来
    print('执行去重规则')
    print(request.url)
    fd=request_fingerprint(request)##进行了加密处理,长度一样
    if fd in self.vister_urls:##如果访问的url在这里的话,就返回true,不执行
    print('存在')
    print(request.url)
    return True
    self.vister_urls.add(fd)


    ##爬虫开始的时候
    def open(self): # can return deferred
    print('开始')

    ##redis,爬虫结束
    def close(self, reason): # can return a deferred
    print('结束')


    ##记录日志的时候
    def log(self, request, spider): # log that a request has been filtered
    print('记录日志')


    '''
    可以让他每次来不执行init方法
    直接是下面的方法,所以init里面定义的set可以一直加值,在进行判断,相当于是一个存放url(不重复)集合

    执行顺序:
    最开始执行settings(有执行去重类,导入模块的时候)
    在执行parse方法,如果settings里面配置了去重的类的话,那么每yield Requets的时候,就会执行这个自定义的去重类:
    去重类执行顺序:先执行from_seen,在执行open,在执行request_seen(多次执行,每yield Request一次的话,就执行一次这个方法),最后执行close
    '''



    连接redis去重处理(放进redis集合里面)

    爬虫里面:
    from   scrapy.http.request  import  Request
    def parse(self, response):
    print('执行操作')
    # obj=response.xpath('//*[@id="dig_lcpage"]/ul/li/a[re:test(@class,"ct_pagepa")]/@href').extract()
    obj=response.xpath('//*[@id="dig_lcpage"]/ul/li/a[re:test(@href,"/all/hot/recent/(d+)")]/@href').extract()
    for i in obj:
    # print(i)
    page='https://dig.chouti.com'+i
    yield Request(url=page,callback=self.parse)#dont_filter=True是不执行去重的,当为false是执行去重的

     settings里面

    DUPEFILTER_CLASS='scrapy_pro.dupfliter.DupFliter'

    去重类里面:
    from scrapy.dupefilter import BaseDupeFilter
    from scrapy.utils.request import request_fingerprint
    import redis
    class DupFliter(BaseDupeFilter):
    def __init__(self):
    self.dupdic=redis.Redis(host='127.0.0.1',port=6379)
    # def request_seen(self,request):
    # url=request_fingerprint(request)
    # if url in self.dupdic:
    # return True
    # self.dupdic.add(url)
    # print('添加成功',request.url)
    def request_seen(self,request):
    url=request_fingerprint(request)
    print('执行去重')
    if url==1:
    self.dupdic.sadd('scrapy_urls', request.url) ##做判断,看是否是相等的
    print('添加成功', request.url)
    return False
    print('已经存在',request.url)
    return True
    # 如果是添加成功的haul,那么久返回fasle,不做处理,如果返回true就会执行下一个yield
  • 相关阅读:
    消息队列非阻塞
    外挂简介
    mfc小工具开发之定时闹钟之---二十四小时时区和时间段
    mfc小工具开发之定时闹钟之---时间获取和音频播放
    mfc小工具开发之定时闹钟之---多线程急线程同步
    mfc小工具开发之定时闹钟之---功能介绍
    8127 timeout!!! 搞死人啊
    RGB565 转换 BMP24
    linux 格式化u盘
    linq分页扩展(转)
  • 原文地址:https://www.cnblogs.com/yunxintryyoubest/p/9940215.html
Copyright © 2020-2023  润新知