增量式爬虫(简易)

增量式爬虫

引言:

    当我们在浏览相关网页的时候会发现,某些网站定时会在原有网页数据的基础上更新一批数据,例如某电影网站会实时更新一批最近热门的电影。小说网站会根据作者创作的进度实时更新最新的章节数据等等。那么,类似的情景,当我们在爬虫的过程中遇到时,我们是不是需要定时更新程序以便能爬取到网站中最近更新的数据呢?

 

一.增量式爬虫

  • 概念:通过爬虫程序监测某网站数据更新的情况,以便可以爬取到该网站更新出的新数据。
  • 如何进行增量式的爬取工作:
    • 在发送请求之前判断这个URL是不是之前爬取过
    • 在解析内容后判断这部分内容是不是之前爬取过
    • 写入存储介质时判断内容是不是已经在介质中存在
      • 分析:

              不难发现,其实增量爬取的核心是去重, 至于去重的操作在哪个步骤起作用,只能说各有利弊。在我看来,前两种思路需要根据实际情况取一个(也可能都用)。第一种思路适合不断有新页面出现的网站,比如说小说的新章节,每天的最新新闻等等;第二种思路则适合页面内容会更新的网站。第三个思路是相当于是最后的一道防线。这样做可以最大程度上达到去重的目的。

  • 去重方法
    • 将爬取过程中产生的url进行存储,存储在redis的set中。当下次进行数据爬取时,首先对即将要发起的请求对应的url在存储的url的set中做判断,如果存在则不进行请求,否则才进行请求。
    • 对爬取到的网页内容进行唯一标识的制定,然后将该唯一表示存储至redis的set中。当下次爬取到网页数据的时候,在进行持久化存储之前,首先可以先判断该数据的唯一标识在redis的set中是否存在,在决定是否进行持久化存储。

二.项目案例

- 需求:爬取4567tv网站中所有的电影详情数据。

爬虫文件:

import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule from redis import Redis from incrementPro.items import IncrementproItem class 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 item

管道文件:


# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html from redis import Redis class 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 

- 需求:爬取糗事百科中的段子和作者数据。

爬虫文件:

import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule from incrementByDataPro.items import IncrementbydataproItem from redis import Redis import hashlib class 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('该条数据已经爬取过了,不需要再次爬取了!!!') 

管道文件:        


# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html from redis import Redis class 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/Majintao/p/10593084.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/483837.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

“中国诺奖”2021未来科学大奖公布:袁国勇、裴伟士、张杰、施敏获奖,总奖金300万美元...

来源:学术头条中国首个由科学家、企业家共同发起的民间公益组织颁发的世界级科学大奖——未来科学大奖,9 月 12 日正式揭晓 2021 年生命科学奖、物质科学奖、数学与计算机科学奖获奖名单。香港大学袁国勇、裴伟士获得生命科学奖。获奖理由:他…

实验二——函数重载,快速排序,类对象

函数重载&#xff1a; #include<iostream> using namespace std; struct complex{ double real; double imaginary; }; int add(int,int); double add(double,double); complex add(complex,complex); int main() { int a12,b13; double a22.0,b23.0; struct complex num…

LeetCode 771. 宝石与石头

题目&#xff1a; 给定字符串J 代表石头中宝石的类型&#xff0c;和字符串 S代表你拥有的石头。 S 中每个字符代表了一种你拥有的石头的类型&#xff0c;你想知道你拥有的石头中有多少是宝石。 J 中的字母不重复&#xff0c;J 和 S中的所有字符都是字母。字母区分大小写&#…

Python——类与对象,异常处理

类 1 class C1: 2 def setdata(self,value): 3 self.data value 4 def display(self): 5 print(self.data) 1 class C2(C1): //继承&#xff0c;2 def display(self): 3 print(C2:, self.data)…

【前沿技术】Facebook 硬件负责人,带摄像头的智能眼镜将在 10 年内成为常态

拍照功能将在十年内成为智能眼镜的标准配置来源&#xff1a;智能研究院在 Facebook 与 Luxottica 的首款智能眼镜合作产品 Ray-Ban Stories 发布后&#xff0c;Facebook 硬件业务负责人 Andrew Bosworth 周五在与 Essilor Luxottica 的首席可穿戴设备官 Rocco Basilico 交谈时表…

LeetCode 1431. 拥有最多糖果的孩子

题目&#xff1a;给你一个数组 candies 和一个整数 extraCandies &#xff0c;其中 candies[i] 代表第 i 个孩子拥有的糖果数目。 对每一个孩子&#xff0c;检查是否存在一种方案&#xff0c;将额外的 extraCandies 个糖果分配给孩子们之后&#xff0c;此孩子有 最多 的糖果。…

#leetcode刷题之路35-搜索插入位置

给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。你可以假设数组中无重复元素。 示例 1:输入: [1,3,5,6], 5输出: 2示例 2:输入: [1,3,5,6], 2输出: 1示例 3:输入: …

9大领域50名青年学者获2021年科学探索奖,单人奖金300万元

来源&#xff1a;科学探索奖官网、科学网等9 月 13 日&#xff0c;2021 年科学探索奖获奖人名单公布&#xff0c;来自 9 个领域的 50 名青年科学家获奖。其中包括 8 名女性科学家&#xff0c;最年轻获奖者仅 32 岁。他们将在 5 年内获得总计 300 万元人民币的奖金&#xff0c;可…

ajax传递数组,后台接收为null解决方法

traditional:true,加上这个就好&#xff0c;默认为false,即允许深度序列化参数&#xff0c;但是servlet api不支持&#xff0c;所有设为true阻止就好了。 $.ajax({ type:post, url:/lst, async:true, data:{"arr_id":arr_id}, traditional:true, s…

多角度回顾因果推断的模型方法

来源&#xff1a;AI干货知识库推断因果关系&#xff0c;是人类思想史与科学史上的重要主题。现代因果推断的研究&#xff0c;始于约尔-辛普森悖论&#xff0c;经由鲁宾因果模型、随机试验等改进&#xff0c;到朱力亚珀尔的因果革命&#xff0c;如今因果科学与人工智能的结合正掀…

torchvision包的主要构成

torchvision包是服务于PyTorch深度学习框架的&#xff0c;主要用来构建计算机视觉模型。 torchvision 主要由以下几部分构成&#xff1a; torchvision.datasets&#xff1a;一些加载数据的函数及常用的数据集接口&#xff1b;torchvision.models&#xff1a;包含常用的模型结…

Eclipse+ADT+Android SDK 搭建安卓开发环境

要求&#xff1a;windows 7 基本操作。运行环境&#xff1a;windows 7(64位); eclipse-jee-luna-SR2-win32(32位);ADT-23.0.4 最近刚开始接触Android(安卓)嵌入式开发&#xff0c;首要问题是搭建Andoid开发环境&#xff0c;由于本人用的是windows7的笔记本&#xff0c;也就只能…

机器学习与数据挖掘简介

机器学习的目的是预测&#xff08;包括分类和回归&#xff09;。 分类是根据输入数据&#xff0c;判别这些数据隶属于哪个类别。 回归则是根据输入数据&#xff0c;计算出一个输出值。输入数据一般为一个向量&#xff0c;向量的各个分量也称为特征&#xff08;Feature&#xff…

骆利群院士最新Science综述:神经环路架构,激发新的AI

来源&#xff1a;ScienceAI编辑&#xff1a;凯霞人脑包含大约 1000 亿个神经元&#xff0c;每个神经元都有数千个突触连接。尽管单个神经元是神经系统的基本单位&#xff0c;但正是它们的突触连接模式使神经元能够为特定功能形成专门的神经环路&#xff0c;从而使大脑成为强大的…

软件设计作业 1

第一部分先列出本次采用Scrum敏捷编程的任务完成情况&#xff0c;并写出心得 酒店管理系统能够极大的方便酒店的工资人员在关于酒店的管理的操作&#xff0c;如客人入住、退房&#xff0c;信息录入、查询等&#xff0c;极大的提高了酒店整体管理活动的工作效率。 使用Scrum使得…

决策树简介与入门

决策树表示对象属性&#xff08;比如贷款用户的年龄、是否有工作、是否有房产、信用评分等&#xff09;和对象类别&#xff08;是否批准其贷款申请&#xff09;之间的一种映射。使用层层推理来实现最终的分类。  根节点&#xff1a;包含样本的全集  内部节点&#xff1a;对…

前端vue实现pdf文件的在线预览

3.前端vue实现pdf文件的在线预览 我是通过 <iframe> 标签就可以满足我工作的 pdf预览需求 如果<iframe> 无法满足需求 &#xff0c; 可以使用pdf.js这个插件&#xff0c;功能强大。 <iframe:src"url"type"application/x-google-chrome-pdf"…

中国科学院院士骆清铭: “看见”大脑

来源&#xff1a;瞭望 新闻周刊编辑&#xff1a;宋若一责任编辑&#xff1a;冀娴贤文&#xff1a;《瞭望》新闻周刊记者 扈永顺 ◇以工业化的方式大规模、标准化地产生数据并绘制脑图谱&#xff0c;将改变神经科学已有的研究方式◇“全脑介观神经联接图谱”大科学计划目前已凝…

Serializer字段和选项

字段 字段构造方式 BooleanField BooleanField() NullBooleanField NullBooleanField() CharField CharField(max_lengthNone, min_lengthNone, allow_blankFalse, trim_whitespaceTrue) EmailField EmailField(max_lengthNone, min_lengthNone, allow_blankFal…

聚类算法 K-Means 简介与入门

K-Means 算法是最简单的一种聚类算法&#xff0c;属于无监督学习算法。 聚类和分类最大的不同在于&#xff1a;分类的目标是事先已知的&#xff0c;而聚类则不一样&#xff0c;聚类事先不知道目标变量是什么&#xff0c;类别没有像分类那样被预先定义出来。 假设我们的样本是 …