感觉我需要先把Scrapy官方文档再过一遍,
收集了一下网上的scrapy面试题,发现面试会碰到什么情况的问题也真的是无法预料。
前言
只说一句,官方文档万岁。
Scrapy QA
对网上见过的问题,进行知识点整理。
Scarapy 数据流
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 基本必问,脑海里最好有一张流程图
1. Engine获得从爬行器中爬行的初始请求。 2. Engine在调度程序中调度请求,并请求下一次抓取请求。 3. 调度程序将下一个请求返回到引擎。 4. 引擎将请求发送到下载器,通过下载器中间件(请参阅process_request())。 5. 页面下载完成后,下载器生成一个响应(带有该页面)并将其发送给引擎,通过下载器中间件(请参阅process_response())。 6. 引擎从下载加载程序接收响应,并将其发送给Spider进行处理,并通过Spider中间件(请参阅process_spider_input())。 7. Spider处理响应,并向引擎返回报废的项和新请求(要跟踪的),通过Spider中间件(请参阅process_spider_output())。 8. 引擎将已处理的项目发送到项目管道,然后将已处理的请求发送到调度程序,并请求可能的下一个请求进行抓取。 9. 这个过程重复(从第1步),直到调度程序不再发出请求。
简单总结: start_request(引擎)>调度器>引擎>(下载中间件)>下载器>(下载中间件)>引擎>(爬虫中间件)>爬虫>(爬虫中间件)>引擎>管道&&调度器> more
|
Scrapy相BeautifulSoup或lxml比较,如何呢?
1 2 3 4 5 6 7 8
| BeautifulSoup 及 lxml 是HTML和XML的分析库。 Scrapy则是 编写爬虫,爬取网页并获取数据的应用框架(application framework)。
Scrapy提供了内置的机制来提取数据(叫做 选择器(selectors))。 但如果您觉得使用更为方便,也可以使用 BeautifulSoup (或 lxml)。 总之,它们仅仅是分析库,可以在任何Python代码中被导入及使用。
换句话说,拿Scrapy与 BeautifulSoup (或 lxml) 比较就好像是拿 jinja2 与 Django 相比。
|
Scrapy支持HTTP代理么?
1
| 必须的,通过 HttpProxyMiddleware 中间件可以实现。当然也可以通过自定义中间件来实现!
|
Scrapy如何爬取属性在不同页面的item呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| 非常基础且常见的问题.. 通过response的meta来进行传递,字典键值对。不但是item,就算是一些自定义参数也可以传。
除了meta,有趣的还有其他特殊方法: dont_redirect dont_retry handle_httpstatus_list handle_httpstatus_all dont_merge_cookies (see cookies parameter of Request constructor) cookiejar dont_cache redirect_urls bindaddress dont_obey_robotstxt download_timeout download_maxsize proxy
顾名思义,估计也能猜出来了。 这里我用最多还有redirect_urls和dont_retry,控制跳转以及控制是否重试。 结合retry或者重定向中间件,还可以针对性的处理爬取过程中碰到的验证码问题。 高端点的还有cookie合并方法。
|
Scrapy我要如何在spider里模拟用户登录呢?
1 2
| 使用FormRequest.from_response()方法 构造好需要用户登录需要的各类参数,然后模拟用户登录。
|
Scrapy是以广度优先还是深度优先进行爬取的呢?
1 2 3 4 5 6 7 8 9
| 默认情况下,Scrapy使用 LIFO 队列来存储等待的请求。 简单的说,就是 深度优先顺序 。 深度优先对大多数情况下是更方便的。 如果您想以 广度优先顺序 进行爬取,你可以设置以下的设定: DEPTH_PRIORITY = 1 SCHEDULER_DISK_QUEUE = 'scrapy.squeue.PickleFifoDiskQueue' SCHEDULER_MEMORY_QUEUE = 'scrapy.squeue.FifoMemoryQueue'
DEPTH_LIMIT 还可以对层级进行有效的限制,根据项目情况来定。
|
Scrapy爬虫有内存泄露/内存爆了/栈溢出了,怎么办?
1 2 3 4 5 6 7 8 9 10
| 加内存条啊(这句话划掉)
解决方案:没有比这更详细的了。 https://scrapy-chs.readthedocs.io/zh_CN/1.0/topics/leaks.html#topics-leaks
我的步骤是这样的: 1. 首先检查编写的中间件,管道(pipeline) 或扩展。例如,在 spider_opened 中分配资源但在 spider_closed 中没有释放它们。 2. 检查是否出现下载速度和管道存储速度是否平衡,如果差距很大,会造成队列积压。 3. 使用 trackref 在telNet下调试内存泄露,具体问题具体分析,其追踪了所有活动(live)的Request, Item及Selector对象的引用。 4. 使用 get_oldest() 方法来看都是什么鬼东西在那卡半天,找出来单独测试然后寻找解决办法。
|
如何让Scrapy减少内存消耗?
1 2 3 4 5 6
| 加内存条啊(这句话划掉)
1. 尽可能减少对 meta 或者 request回调函数 的传递对象的引用 2. 让Requests, Response及Items的对象具有完整有限的生命周期: 被创建,使用,最后被销毁。尤其是销毁! 3. 中间件,管道(pipeline) 或扩展.py 中,一定要有有始有终。记得在 spider_closed 中没有释放分配的资源。
|
spider中可以使用基本HTTP认证么?
1
| HttpAuthMiddleware 有关的验证中间件,了解一下。
|
(未完持续..)