zoukankan      html  css  js  c++  java
  • python爬虫用redis去重多种方法

    什么是增量爬虫
    爬虫过程中,常常要对目标网站的新数据进行抓取,遇到已经爬过的网页需要进行过滤。本文介绍用redis数据库的高效去重。
    把所有爬过的url都放在redis中,以后每次爬取链接之前,先把url添加进去,如果能添加进去,说明是没爬过的,如果添加不进去,说明该链接有爬取过。

    方法1

    普通爬取时,核心的代码逻辑如下

    import hashlib
    import redis
     
    def get_md5(val):
        """把目标数据进行哈希,用哈希值去重更快"""
        md5 = hashlib.md5()
        md5.update(val.encode('utf-8'))
        return md5.hexdigest()
     
    def add_url(url):
        red = redis.Redis(host='106.1xxx', password='redixxxx', port=6379, db=0)
        res = red.sadd('TEST:urlset', get_md5(url)) # 注意是 保存set的方式
        if res == 0:  # 若返回0,说明插入不成功,表示有重复
            return False
        else:
            return True
     
    if __name__ == '__main__':
        print(add_url('https://www.taobao.com'))
    

    方法2

    可以把请求的response进行哈希,然后保存,其他的逻辑同方法一。
    scrapy框架中,去重的核心代码是:(这里也是先对url进行判断,没爬过的才爬取)
    主脚本的代码示例

    import scrapy
    from scrapy.linkextractors import LinkExtractor
    from scrapy.spiders import CrawlSpider, Rule
    from redis import Redis
    from TestProgram.items import TestProgramItem
    class TestSpider(CrawlSpider):
        name = 'ttt'
        # allowed_domains = ['www.xxx.com']
        start_urls = ['https://www.xxx.html']
     
        rules = (
            Rule(LinkExtractor(allow=r'/index.php/d+.html'), callback='parse_item', follow=True),
        )
     
        def parse_item(self, response):
            conn = Redis(host='127.0.0.1',port=6379)
            detail_url_list= response.xpath('//li[@class="c/@href').extract()
            for url in detail_url_list:
                ex = conn.sadd('test_url',url)
                #等于1 的时候 说明数据还没有存储到redis中  等于0 的时候 说明redis中已经存在该数据
                if ex == 1:
                    yield scrapy.Request(url=url,callback=self.parse_detail)
                else:
                    print("无数据更新")
        def parse_detail(self,response):
            item = TestProgramItem()
            item['name']=response.xpath('/html/bo/text()').extract_first()
            item['age']=response.xpath('/html/bo/text()').extract_first()
            yield item
    

    pipeline中的脚本示例:(因为在主脚本中已经过滤了,这里就不用其他的操作,正常操作即可)

    from redis import Redis
    class TestProramPipeline(object):
        conn = None
        def open_spider(self,spider):
            self.conn = Redis(host='127.0.0.1',port=6379)
     
        def process_item(self, item, spider):
            self.conn.lpush('movie_data',item)
            return item
    
  • 相关阅读:
    庆祝 杀马下载量突破300万!
    智能实验室-杀马(Defendio) 4.26.0.940
    智能实验室-全能优化(Guardio) 4.992.0.900
    智能实验室-杀马(Defendio) 4.17.0.850
    目前为止功能最全的基于silverlight4(beta)的摄像头应用
    Discuz!NT负载均衡方案
    Discuz!NT跨站缓存同步
    Discuz!NT负载均衡解决方案(HA)之LVS(Linux Virtual Server)
    Discuz!NT企业版之Sphinx全文搜索(下)
    Discuz!NT千万级数据量上的两驾马车TokyoCabinet,MongoDB
  • 原文地址:https://www.cnblogs.com/gqv2009/p/15190987.html
Copyright © 2011-2022 走看看