增量式爬虫通过爬虫程序监测某网站数据更新的情况,以便可以爬取到该网站更新出的新数据。增量式爬虫核心在于跳过之前已经爬去过的数据,也就是实现请求去重!
去重方法
- 将爬取过程中产生的url进行存储,存储在redis的set中。当下次进行数据爬取时,首先对即将要发起的请求对应的url在存储的url的set中做判断,如果存在则不进行请求,否则才进行请求。
- 对爬取到的网页内容进行唯一标识的制定,然后将该唯一表示存储至redis的set中。当下次爬取到网页数据的时候,在进行持久化存储之前,首先可以先判断该数据的唯一标识在redis的set中是否存在,在决定是否进行持久化存储。
增量式爬虫案例
4567电影网电影及描述信息(http://www.4567kan.com/index.php/vod/show/id/5.html)
1.创建爬虫项目(基于CrawlSpider类)
scrapy startproject zls_moviePro
cd zls_moviePro
scrapy genspider -t crawl zls_movieTest www.xxx.com
2.编写爬虫文件zls_movieTest.py
1 # -*- coding: utf-8 -*- 2 import scrapy 3 from scrapy.linkextractors import LinkExtractor 4 from scrapy.spiders import CrawlSpider, Rule 5 from redis import Redis 6 from zls_moviePro.items import ZlsMovieproItem 7 8 #获取电影名称及对应的描述 9 class ZlsMovietestSpider(CrawlSpider): 10 #连接redis数据库 11 conn = Redis(host='127.0.0.1', port=6379) 12 name = 'zls_movieTest' 13 # allowed_domains = ['www.xxx.com'] 14 start_urls = ['http://www.4567kan.com/index.php/vod/show/id/5.html'] 15 16 rules = ( 17 Rule(LinkExtractor(allow=r'index.php/vod/show/id/5/page/d+.html'), callback='parse_item', follow=True), 18 ) 19 20 def parse_item(self, response): 21 22 li_list=response.xpath('/html/body/div[1]/div/div/div/div[2]/ul/li') 23 for li in li_list: 24 item = ZlsMovieproItem() 25 item['name'] = li.xpath('.//div[@class="stui-vodlist__detail"]/h4/a/text()').extract_first() 26 url='http://www.4567kan.com'+li.xpath('.//div[@class="stui-vodlist__detail"]/h4/a/@href').extract_first() 27 #经电影详情的url存在redis数据库的集合中,可以去重进行判断是否爬取过 28 ex = self.conn.sadd('movie_detail_urls', url)#添加成功返回1,否则为0 29 if ex==1: 30 print('数据有更新,正在下载...') 31 yield scrapy.Request(url=url, callback=self.parse_detail, meta={'item': item}) 32 else: 33 print('暂无数据更新!') 34 35 def parse_detail(self, response): 36 movie_desc = response.xpath('/html/body/div[1]/div/div/div/div[2]/p[5]/span[2]/text()').extract_first() 37 item = response.meta['item'] 38 item['desc'] = movie_desc 39 yield item
3.items.py字段属性定义
1 import scrapy 2 3 4 class ZlsMovieproItem(scrapy.Item): 5 # define the fields for your item here like: 6 name = scrapy.Field() 7 desc=scrapy.Field() 8 pass
4.pipelines.py管道配置
1 class ZlsMovieproPipeline(object): 2 def process_item(self, item, spider): 3 spider.conn.lpush('movie_data',item)#spider为爬虫文件类的实例化对象,将item字典数据存储在redis数据库的movie_data对应的列表中 4 return item
5.settings.py配置文件
1 #UA伪装 2 USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36" 3 #robots协议 4 ROBOTSTXT_OBEY = False 5 #日志输出等级 6 LOG_LEVEL="ERROR" 7 8 #开启管道 9 ITEM_PIPELINES = { 10 'zls_moviePro.pipelines.ZlsMovieproPipeline': 300, 11 }
6.启动爬虫项目
scrapy crawl zls_movieTest