博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
爬虫篇 ---增量式爬虫
阅读量:5297 次
发布时间:2019-06-14

本文共 4187 字,大约阅读时间需要 13 分钟。

What is 增量式爬虫?

  用来 监测 网站数据更新的情况,只会爬取网站中更新出来的新数据

增量式爬虫的核心

  去重,因为你爬取到的数据是不可以出现重复的

怎么进行增量式爬取呢?

  • 在发送请求之前判断这个URL是不是之前爬取过
  • 在解析内容后判断这部分内容是不是之前爬取过
  • 写入存储到 redis 时判断内容是不是已经在介质中存在
    #总结分析    对比三种方式增量爬取的核心是去重, 至于去重的操作在哪个步骤起作用,只能说各有利弊。在我看来,前两种思路需要根据实际情况取一个(也可能都用)。#第一种思路适合不断有新页面出现的网站,比如说小说的新章节,每天的最新新闻等等;#第二种思路则适合页面内容会更新的网站。#第三个思路是相当于是最后的一道防线。这样做可以最大程度上达到去重的目的。

去重方法

1. 将爬取过程中产生的url进行存储,存储在redis的set中。当下次进行数据爬取时,首先对即将要发起的请求对应的url在存储的url的set中做判断,如果存在则不进行请求,否则才进行请求。

2. 对爬取到的网页内容进行唯一标识的制定,然后将该唯一表示存储至redis的set中。当下次爬取到网页数据的时候,在进行持久化存储之前,首先可以先判断该数据的唯一标识在redis的set中是否存在,在决定是否进行持久化存储。

项目实例

demo1 爬取4567tv网站中所有的电影详情数据

spider.pyimport scrapyfrom scrapy.linkextractors import LinkExtractorfrom scrapy.spiders import CrawlSpider, Rulefrom redis import Redisfrom incrementPro.items import IncrementproItemclass MovieSpider(CrawlSpider):    name = 'movie'    # allowed_domains = ['www.xxx.com']    start_urls = ['http://www.4567tv.tv/frim/index7-11.html']    rules = (        Rule(LinkExtractor(allow=r'/frim/index7-\d+\.html'), callback='parse_item', follow=True),    )    #创建redis链接对象    conn = Redis(host='127.0.0.1',port=6379)    def parse_item(self, response):        li_list = response.xpath('//li[@class="p1 m1"]')        for li in li_list:            #获取详情页的url            detail_url = 'http://www.4567tv.tv'+li.xpath('./a/@href').extract_first()            #将详情页的url存入redis的set中            ex = self.conn.sadd('urls',detail_url)            if ex == 1:                print('该url没有被爬取过,可以进行数据的爬取')                yield scrapy.Request(url=detail_url,callback=self.parst_detail)            else:                print('数据还没有更新,暂无新数据可爬取!')    #解析详情页中的电影名称和类型,进行持久化存储    def parst_detail(self,response):        item = IncrementproItem()        item['name'] = response.xpath('//dt[@class="name"]/text()').extract_first()        item['kind'] = response.xpath('//div[@class="ct-c"]/dl/dt[4]//text()').extract()        item['kind'] = ''.join(item['kind'])        yield itempipeline.pyfrom redis import Redisclass IncrementproPipeline(object):    conn = None    def open_spider(self,spider):        self.conn = Redis(host='127.0.0.1',port=6379)    def process_item(self, item, spider):        dic = {            'name':item['name'],            'kind':item['kind']        }        print(dic)        self.conn.lpush('movieData',dic)        return item

demo2 爬取糗事百科中的段子和作者数据。

spider.pyimport scrapyfrom scrapy.linkextractors import LinkExtractorfrom scrapy.spiders import CrawlSpider, Rulefrom incrementByDataPro.items import IncrementbydataproItemfrom redis import Redisimport hashlibclass QiubaiSpider(CrawlSpider):    name = 'qiubai'    # allowed_domains = ['www.xxx.com']    start_urls = ['https://www.qiushibaike.com/text/']    rules = (        Rule(LinkExtractor(allow=r'/text/page/\d+/'), callback='parse_item', follow=True),        Rule(LinkExtractor(allow=r'/text/$'), callback='parse_item', follow=True),    )    #创建redis链接对象    conn = Redis(host='127.0.0.1',port=6379)    def parse_item(self, response):        div_list = response.xpath('//div[@id="content-left"]/div')        for div in div_list:            item = IncrementbydataproItem()            item['author'] = div.xpath('./div[1]/a[2]/h2/text() | ./div[1]/span[2]/h2/text()').extract_first()            item['content'] = div.xpath('.//div[@class="content"]/span/text()').extract_first()            #将解析到的数据值生成一个唯一的标识进行redis存储            source = item['author']+item['content']            source_id = hashlib.sha256(source.encode()).hexdigest()            #将解析内容的唯一表示存储到redis的data_id中            ex = self.conn.sadd('data_id',source_id)            if ex == 1:                print('该条数据没有爬取过,可以爬取......')                yield item            else:                print('该条数据已经爬取过了,不需要再次爬取了!!!')pipeline.pyfrom redis import Redisclass IncrementbydataproPipeline(object):    conn = None    def open_spider(self, spider):        self.conn = Redis(host='127.0.0.1', port=6379)    def process_item(self, item, spider):        dic = {            'author': item['author'],            'content': item['content']        }        # print(dic)        self.conn.lpush('qiubaiData', dic)        return item

 

转载于:https://www.cnblogs.com/CrazySheldon1/p/10839537.html

你可能感兴趣的文章
学习js第二天小结
查看>>
vue methods 中方法的相互调用
查看>>
负载均衡
查看>>
hdu 4865 dp
查看>>
SSH框架总结(框架分析+环境搭建+实例源代码下载)
查看>>
mac笔记本上的工具
查看>>
php 3des加密 兼容JAVA 多么痛的领悟呀
查看>>
@NOI模拟2017.07.02 - T1@ Attack
查看>>
搭建iview环境
查看>>
人生各个阶段特点和理财相关
查看>>
如何向领导学习
查看>>
java-swingButton
查看>>
[每天解决一问题系列 - 0002] Xcopy cannot copy file with long directory
查看>>
winform listview控件
查看>>
Android——requestWindowFeature
查看>>
iOS UDP 简易交互
查看>>
4-10 二分查找
查看>>
后台网页编辑器(带图片上传)
查看>>
部署---阿里云服务器,linux, ubuntu ,部署django用到的一些命令
查看>>
Linux awk
查看>>