我是靠谱客的博主 温婉衬衫,这篇文章主要介绍067、Scrapy常见问题1. 描述下scrapy 框架运行的机制?2. 谈谈你对Scrapy 的理解?3. 怎么样让 scrapy 框架发送一个 post 请求(具体写出来)4. 怎么判断网站是否更新?5. 图片、视频爬取怎么绕过防盗连接,或者说怎么获取正确的链接地址?6. 你爬出来的数据量大概有多大?大概多长时间爬一次?7. 增量爬取8. 爬虫向数据库存数据开始和结束都会发一条消息,是 scrapy 哪个模块实现的?9. 爬取下来的数据如何去重,说一下具体的算法依据11. 怎么设置深度爬取,现在分享给大家,希望可以做个参考。

1. 描述下scrapy 框架运行的机制?

从 start_urls 里获取第一批 url 并发送请求,请求由引擎交给调度器入请求队列,获取完毕后,调度器将请求队列里的请求交给下载器去获取请求对应的响应资源,并将响应交给自己编写的解析方法做提取处理:

1. 如果提取出需要的数据,则交给管道文件处理;

2. 如果提取出 url,则继续执行之前的步骤(发送 url 请求,并由引擎将请求交给调度器入队列...), 直到请求队列里没有请求,程序结束。

3. 根据 scrapy 的流程图,描述出五大组件、两个中间件,以及完成一个请求的流程。

 

2. 谈谈你对Scrapy 的理解?

scrapy 是一个为了爬取网站数据,提取结构性数据而编写的应用框架,我们只需要实现少量代码, 就能够快速的抓取到数据内容。Scrapy 使用了 Twisted 异步网络框架来处理网络通讯,可以加快我们的下载速度,不用自己去实现异步框架,并且包含了各种中间件接口,可以灵活的完成各种需求。

scrapy 框架的工作流程:

1. 首先 Spiders(爬虫)将需要发送请求的 url(requests)经 ScrapyEngine(引擎)交给 Scheduler

(调度器)。

2. Scheduler(排序,入队)处理后,经 ScrapyEngine,DownloaderMiddlewares(可选,主要有 User_Agent, Proxy 代理)交给 Downloader。

3. Downloader 向互联网发送请求,并接收下载响应(response)。将响应(response)经

ScrapyEngine,SpiderMiddlewares(可选)交给 Spiders。

4. Spiders 处理 response,提取数据并将数据经 ScrapyEngine 交给ItemPipeline 保存(可以是本地,可以是数据库)。提取 url 重新经 ScrapyEngine 交给 Scheduler 进行下一个循环。直到无 Url 请求程序停止结束。

 

3. 怎么样让 scrapy 框架发送一个 post 请求(具体写出来)

使 用 FormRequest

 

4. 怎么判断网站是否更新?

静态页面可以考虑使用 http 的 head 方法查看网站的最后更新时间

如果前者行不通,则需要对数据进行标识,如利用加密算法生成指纹,然后定期发起请求获取数据,比对指纹是否一致,如果一致,说明网站没有更新;反之说明更新。

 

5. 图片、视频爬取怎么绕过防盗连接,或者说怎么获取正确的链接地址?

自定义 Referer(建议自行 Google 相关知识)。

 

6. 你爬出来的数据量大概有多大?大概多长时间爬一次?

无标准答案,根据自己爬取网站回答即可(几百万,几千万,亿级)。 根据项目需求来定,另外并发量根据网站反爬和机器数量带宽大小来计算

 

7. 增量爬取

实现一个持久化的请求队列

增量爬取即保存上一次状态,本次抓取时与上次比对,如果不在上次的状态中,便视为增量,保存下来。对于 scrapy 来说,上一次的状态是抓取的特征数据和上次爬取的

request 队列(url 列表),request 队列可以通过 request 队列可以通过

scrapy.core.scheduler 的 pending_requests 成员得到,在爬虫启动时导入上次爬取的特征数据,并且用上次 request 队列的数据作为 start url 进行爬取,不在上一次状态中的数据便保存。

选用 BloomFilter 原因:对爬虫爬取数据的保存有多种形式,可以是数据库,可以是磁盘文件等,不管是数据库,还是磁盘文件,进行扫描和存储都有很大的时间和空间上的开

销,为了从时间和空间上提升性能,故选用 BloomFilter 作为上一次爬取数据的保存。保存的特征数据可以是数据的某几项,即监控这几项数据,一旦这几项数据有变化,便视为增

量持久化下来,根据增量的规则可以对保存的状态数据进行约束。比如:可以选网页更新的时间,索引次数或是网页的实际内容,cookie 的更新等。

 

8. 爬虫向数据库存数据开始和结束都会发一条消息,是 scrapy 哪个模块实现的?

Scrapy 使用信号来通知事情发生,因此答案是 signals 模块。

 

9. 爬取下来的数据如何去重,说一下具体的算法依据

1. 通过 MD5 生成电子指纹来判断页面是否改变

2. nutch 去重。nutch 中 digest 是对采集的每一个网页内容的 32 位哈希值,如果两个网页内容完全一样,它们的 digest 值肯定会一样。

数据量不大时,可以直接放在内存里面进行去重,python 可以使用set()进行去重。当去重数据需要持久化时可以使用 redis 的 set 数据结构。

当数据量再大一点时,可以用不同的加密算法先将长字符串压缩成 16/32/40 个字符,再使用上面两种方法去重。

当数据量达到亿(甚至十亿、百亿)数量级时,内存有限,必须用“位”来去重,才能够满足需求。Bloomfilter 就是将去重对象映射到几个内存“位”,通过几个位的 0/1 值来判断一个对象是否已经存在。

然而 Bloomfilter 运行在一台机器的内存上,不方便持久化(机器 down 掉就什么都没啦),也不方便分布式爬虫的统一去重。如果可以在 Redis 上申请内存进行 Bloomfilter,以上两个问题就都能解决了。

simhash 最牛逼的一点就是将一个文档,最后转换成一个 64 位的字节,暂且称之为特征字,然后判断重复只需要判断他们的特征字的距离是不是<n(根据经验这个 n 一般取值为 3),就可以判断两个文档是否相似。

可见 scrapy_redis 是利用 set 数据结构来去重的,去重的对象是 request 的 fingerprint(其实就是用 hashlib.sha1()对 request 对象的某些字段信息进行压缩)。其实 fp 就是 request 对象加密压缩后的一个字符串(40 个字符,0~f)。

优点:

1)scrapy 是 异 步 的2)采取可读性更强的 xpath 代替正则

3) 强大的统计和 log 系统

4) 同时在不同的 url 上爬行

5) 支持 shell 方式,方便独立调试

5)写 middleware,方便写一些统一的过滤器6)通过管道的方式存入数据库

缺点:

1) 基于 python 的爬虫框架,扩展性比较差

2) 基于 twisted 框架,运行中的 exception 是不会干掉 reactor(反应器),并且异步框架出错后是不会停掉其他任务的,数据出错后难以察觉。

 

11. 怎么设置深度爬取?

通过在 settings.py 中设置 depth_limit 的值可以限制爬取深度,这个深度是与 start_urls 中定义 url 的相对值。也就是相对 url 的深度。若定义 url 为

http://www.domz.com/game/,depth_limit=1 那么限制爬取的只能是此 url 下一级的网页。深度大于设置值的将被忽视。

 

1. scrapy 和scrapy-redis 有什么区别?为什么选择redis 数据库?

scrapy 是一个 Python 爬虫框架,爬取效率极高,具有高度定制性,但是不支持分布式。而scrapy-redis 一套基于redis 数据库、运行在 scrapy 框架之上的组件,可以让 scrapy 支持分布式策略,

Slaver 端共享 Master 端 redis 数据库里的 item 队列、请求队列和请求指纹集合。

为什么选择 redis 数据库,因为 redis 支持主从同步,而且数据都是缓存在内存中的,所以基于 redis 的分布式爬虫,对请求和数据的高频读取效率非常高。

 

3. 什么是分布式存储?

传统定义:分布式存储系统是大量 PC 服务器通过 Internet 互联,对外提供一个整体的服务。分布式存储系统具有以下的几个特性:

可扩展 :分布式存储系统可以扩展到几百台甚至几千台这样的一个集群规模,系统的整体性能线性增长。

低成本 :分布式存储系统的自动容错、自动负载均衡的特性,允许分布式存储系统可以构建在低成本的服务器上。另外,线性的扩展能力也使得增加、减少服务器的成本低, 实现分布式存储系统的自动运维。

高性能 :无论是针对单台服务器,还是针对整个分布式的存储集群,都要求分布式存储系统具备高性能。

易用 :分布式存储系统需要对外提供方便易用的接口,另外,也需要具备完善的监控、运维工具,并且可以方便的与其他的系统进行集成。

布式存储系统的挑战主要在于数据和状态信息的持久化,要求在自动迁移、自动容错和并发读写的过程中,保证数据的一致性。

容错:可以快速检测到服务器故障,并自动的将在故障服务器上的数据进行迁移。

负载均衡:新增的服务器在集群中保障负载均衡?数据迁移过程中保障不影响现有的服务。

事务与并发控制:实现分布式事务。

易用性:设计对外接口,使得设计的系统易于使用。

 

4. 你所知道的分布式爬虫方案有哪些?

三种分布式爬虫策略:

1. Slaver 端从 Master 端拿任务(Request/url/ID)进行数据抓取,在抓取数据的同时也生成新任务,并将任务抛给 Master。Master 端只有一个 Redis 数据库,负责对 Slaver 提交的任务进行去重、加入待爬队列。

优点: scrapy-redis 默认使用的就是这种策略,我们实现起来很简单,因为任务调度

等工作 scrapy-redis 都已经帮我们做好了,我们只需要继承 RedisSpider、指定 redis_key 就行了。

缺点: scrapy-redis 调度的任务是 Request 对象,里面信息量比较大(不仅包含 url, 还有 callback 函数、headers 等信息),导致的结果就是会降低爬虫速度、而且会占用

Redis 大量的存储空间。当然我们可以重写方法实现调度 url 或者用户 ID。

2. Master 端跑一个程序去生成任务(Request/url/ID)。Master 端负责的是生产任务, 并把任务去重、加入到待爬队列。Slaver 只管从 Master 端拿任务去爬。

优点: 将生成任务和抓取数据分开,分工明确,减少了 Master 和 Slaver 之间的数据交流;Master 端生成任务还有一个好处就是:可以很方便地重写判重策略(当数据量大时优化判重的性能和速度还是很重要的)。

缺点: 像 QQ 或者新浪微博这种网站,发送一个请求,返回的内容里面可能包含几十个待爬的用户 ID,即几十个新爬虫任务。但有些网站一个请求只能得到一两个新任务,并且返回的内容里也包含爬虫要抓取的目标信息,如果将生成任务和抓取任务分开反而会降

低爬虫抓取效率。毕竟带宽也是爬虫的一个瓶颈问题,我们要秉着发送尽量少的请求为原则,同时也是为了减轻网站服务器的压力,要做一只有道德的 Crawler。所以,视情况而定。

3. Master 中只有一个集合,它只有查询的作用。Slaver 在遇到新任务时询问 Master 此任务是否已爬,如果未爬则加入 Slaver 自己的待爬队列中,Master 把此任务记为已爬。它和策略一比较像,但明显比策略一简单。策略一的简单是因为有 scrapy-redis 实现了

scheduler 中间件,它并不适用于非 scrapy 框架的爬虫。

优点: 实现简单,非 scrapy 框架的爬虫也适用。Master 端压力比较小,Master 与

Slaver 的数据交流也不大。

缺点:“健壮性”不够,需要另外定时保存待爬队列以实现“断点续爬”功能。各 Slaver 的待爬任务不通用。

如果把 Slaver 比作工人,把 Master 比作工头。策略一就是工人遇到新任务都上报给工头,需要干活的时候就去工头那里领任务;策略二就是工头去找新任务,工人只管从工头那里领任务干活;策略 三就是工人遇到新任务时询问工头此任务是否有人做了,没有的话工人就将此任务加到自己的“行程表”。

 

5. 除了 scrapy-redis,有做过其他的分布式爬虫吗?

Celery、gearman 等,参考其他分布式爬虫策略。

 

6. 在爬取的时候遇到某些内容字段缺失怎么判断及处理?

判读字段缺失,做异常处理即可。

最后

以上就是温婉衬衫最近收集整理的关于067、Scrapy常见问题1. 描述下scrapy 框架运行的机制?2. 谈谈你对Scrapy 的理解?3. 怎么样让 scrapy 框架发送一个 post 请求(具体写出来)4. 怎么判断网站是否更新?5. 图片、视频爬取怎么绕过防盗连接,或者说怎么获取正确的链接地址?6. 你爬出来的数据量大概有多大?大概多长时间爬一次?7. 增量爬取8. 爬虫向数据库存数据开始和结束都会发一条消息,是 scrapy 哪个模块实现的?9. 爬取下来的数据如何去重,说一下具体的算法依据11. 怎么设置深度爬取的全部内容,更多相关067、Scrapy常见问题1.内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(72)

评论列表共有 0 条评论

立即
投稿
返回
顶部