python爬虫常见面试题(二)
前言
之所以在这里写下python爬虫常见面试题及解答,一是用作笔记,方便日后回忆;二是给自己一个和大家交流的机会,互相学习、进步,希望不正之处大家能给予指正;三是我也是互联网寒潮下岗的那批人之一,为了找工作而做准备。
一、题目部分
1、scrapy框架专题部分(很多面试都会涉及到这部分)
(1)请简要介绍下scrapy框架。
(2)为什么要使用scrapy框架?scrapy框架有哪些优点?
(3)scrapy框架有哪几个组件/模块?简单说一下工作流程。
(4)scrapy如何实现分布式抓取?
2、其他常见问题。
(1)爬虫使用多线程好?还是多进程好?为什么?
(2)http和https的区别?
(3)数据结构之堆,栈和队列的理解和实现。
二、解答部分
1、scrapy框架专题部分
(1)请简要介绍下scrapy框架。
scrapy 是一个快速(fast)、高层次(high-level)的基于 python 的 web 爬虫构架,用于抓取web站点并从页面中提取结构化的数据。scrapy 使用了 Twisted异步网络库来处理网络通讯。
(2)为什么要使用scrapy框架?scrapy框架有哪些优点?
- 它更容易构建大规模的抓取项目
- 它异步处理请求,速度非常快
- 它可以使用自动调节机制自动调整爬行速度
(3)scrapy框架有哪几个组件/模块?简单说一下工作流程。
Scrapy Engine: 这是引擎,负责Spiders、ItemPipeline、Downloader、Scheduler中间的通讯,信号、数据传递等等!(像不像人的身体?)
Scheduler(调度器): 它负责接受引擎发送过来的requests请求,并按照一定的方式进行整理排列,入队、并等待Scrapy Engine(引擎)来请求时,交给引擎。
Downloader(下载器):负责下载Scrapy Engine(引擎)发送的所有Requests请求,并将其获取到的Responses交还给Scrapy Engine(引擎),由引擎交给Spiders来处理,
Spiders:它负责处理所有Responses,从中分析提取数据,获取Item字段需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheduler(调度器),
Item Pipeline:它负责处理Spiders中获取到的Item,并进行处理,比如去重,持久化存储(存数据库,写入文件,总之就是保存数据用的)
Downloader Middlewares(下载中间件):你可以当作是一个可以自定义扩展下载功能的组件
Spider Middlewares(Spider中间件):你可以理解为是一个可以自定扩展和操作引擎和Spiders中间‘通信‘的功能组件(比如进入Spiders的Responses;和从Spiders出去的Requests)
整体架构如下图:

工作流程:
数据在整个Scrapy的流向:
程序运行的时候,
引擎:Hi!Spider, 你要处理哪一个网站?
Spiders:我要处理23wx.com
引擎:你把第一个需要的处理的URL给我吧。
Spiders:给你第一个URL是XXXXXXX.com
引擎:Hi!调度器,我这有request你帮我排序入队一下。
调度器:好的,正在处理你等一下。
引擎:Hi!调度器,把你处理好的request给我,
调度器:给你,这是我处理好的request
引擎:Hi!下载器,你按照下载中间件的设置帮我下载一下这个request
下载器:好的!给你,这是下载好的东西。(如果失败:不好意思,这个request下载失败,然后引擎告诉调度器,这个request下载失败了,你记录一下,我们待会儿再下载。)
引擎:Hi!Spiders,这是下载好的东西,并且已经按照Spider中间件处理过了,你处理一下(注意!这儿responses默认是交给def parse这个函数处理的)
Spiders:(处理完毕数据之后对于需要跟进的URL),Hi!引擎,这是我需要跟进的URL,将它的responses交给函数 def xxxx(self, responses)处理。还有这是我获取到的Item。
引擎:Hi !Item Pipeline 我这儿有个item你帮我处理一下!调度器!这是我需要的URL你帮我处理下。然后从第四步开始循环,直到获取到你需要的信息,
注意!只有当调度器中不存在任何request了,整个程序才会停止,(也就是说,对于下载失败的URL,Scrapy会重新下载。)
以上就是Scrapy整个流程了。
(4)scrapy如何实现分布式抓取?
可以借助scrapy_redis类库来实现。
在分布式爬取时,会有master机器和slave机器,其中,master为核心服务器,slave为具体的爬虫服务器。
我们在master服务器上搭建一个redis数据库,并将要抓取的url存放到redis数据库中,所有的slave爬虫服务器在抓取的时候从redis数据库中去链接,由于scrapy_redis自身的队列机制,slave获取的url不会相互冲突,然后抓取的结果最后都存储到数据库中。master的redis数据库中还会将抓取过的url的指纹存储起来,用来去重。相关代码在dupefilter.py文件中的request_seen()方法中可以找到。
去重问题:
dupefilter.py 里面的源码:
def request_seen(self, request):
fp = request_fingerprint(request)
added = self.server.sadd(self.key, fp)
return not added
去重是把 request 的 fingerprint 存在 redis 上,来实现的。
2、其他常见问题。
(1)爬虫使用多线程好?还是多进程好?为什么?
对于IO密集型代码(文件处理,网络爬虫),多线程能够有效提升效率(单线程下有IO操作会进行IO等待,会造成不必要的时间等待,而开启多线程后,A线程等待时,会自动切换到线程B,可以不浪费CPU的资源,从而提升程序执行效率)。
在实际的采集过程中,既考虑网速和相应的问题,也需要考虑自身机器硬件的情况,来设置多进程或者多线程。
(2)http和https的区别?
A. http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
B. http适合于对传输速度、安全性要求不是很高,且需要快速开发的应用。如web应用,小的手机游戏等等。而https适用于任何场景。
(3)数据结构之堆,栈和队列的理解和实现。
栈(stacks):栈的特点是后进先出。只能通过访问一端来实现数据的储存和检索的线性数据结构。
队列(queue):队列的特点是先进先出。元素的增加只能在一端,元素的删除只能在另一端。增加的一端称为队尾,删除的一端称为队首。
栈:
stack = [1, 2, 3]
stack.append(4)
stack.append(5)
print(stack)
stack.pop()
stack.pop()
print(stack)
输出结果:
[1, 2, 3, 4, 5]
[1, 2, 3]
队列:
from collections import deque queue = deque(['Eric', 'John', 'Michael'])
queue.append('Terry')
queue.append('Graham')
print(queue)
queue.popleft()
print(queue)
输出结果:
deque(['Eric', 'John', 'Michael', 'Terry', 'Graham'])
deque(['John', 'Michael', 'Terry', 'Graham'])
这里还会有一个常见的问题,栈溢出的常见情况及解决方案。
什么是栈溢出?
因为栈一般默认为1-2m,一旦出现死循环或者是大量的递归调用,在不断的压栈过程中,造成栈容量超过1m而导致溢出。
栈溢出的几种情况?
1、局部数组过大。当函数内部数组过大时,有可能导致堆栈溢出。
2、递归调用层次太多。递归函数在运行时会执行压栈操作,当压栈次数太多时,也会导致堆栈溢出。
解决方法:
1、用栈把递归转换成非递归。
2、增大栈空间。
python爬虫常见面试题(二)的更多相关文章
- python爬虫常见面试题(一)
前言 之所以在这里写下python爬虫常见面试题及解答,一是用作笔记,方便日后回忆:二是给自己一个和大家交流的机会,互相学习.进步,希望不正之处大家能给予指正:三是我也是互联网寒潮下岗的那批人之一,为 ...
- java常见面试题(二)
1.java集合类 Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements).JavaSDK不提供直接继承自Collect ...
- Mybatis常见面试题 二
1.mybatis是什么? (1)mybatis是一个优秀的基于java的持久层框架,它内部封装了jdbc,使开发者只需要关注sql语句本身,而不需要花费精力去处理加载驱动.创建连接.创建state ...
- Hive 常见面试题(二)
1.Hive行转列和列转行如何实现? 行转列 使用 concat_ws 实现行转列. 例如: select user_id, concat_ws(',',collect_list(order_id)) ...
- 整理的最全 python常见面试题(基本必考)
整理的最全 python常见面试题(基本必考) python 2018-05-17 作者 大蛇王 1.大数据的文件读取 ① 利用生成器generator ②迭代器进行迭代遍历:for line in ...
- 整理的最全 python常见面试题
整理的最全 python常见面试题(基本必考)① ②③④⑤⑥⑦⑧⑨⑩ 1.大数据的文件读取: ① 利用生成器generator: ②迭代器进行迭代遍历:for line in file; 2.迭代 ...
- PHP常见面试题汇总(二)
PHP常见面试题汇总(二) //第51题:统计一维数组中所有值出现的次数?返回一个数组,其元素的键名是原数组的值;键值是该值在原数组中出现的次数 $array=array(4,5,1,2,3,1, ...
- iOS常见面试题汇总
iOS常见面试题汇总 1. 什么是 ARC? (ARC 是为了解决什么问题而诞生的?) ARC 是 Automatic Reference Counting 的缩写, 即自动引用计数. 这是苹果在 i ...
- 【javascript常见面试题】常见前端面试题及答案
转自:http://www.cnblogs.com/syfwhu/p/4434132.html 前言 本文是在GitHub上看到一个大牛总结的前端常见面试题,很多问题问的都很好,很经典.很有代表性.上 ...
随机推荐
- decimal and double ToString problem
decimal d2 = 0.0000002500m; Console.WriteLine(d2.ToString()); double d3 = 0.0000002500; Console.Writ ...
- 如何加速tomcat启动速度
在tomcat启动的时候,我们可以做一些优化设置来使得tomcat的启动更快速,下面是一些常见的优化加速启动的方法建议(以tomcat-7.+为例说明). 1. Jars包 1.1.将一些不必要的j ...
- R语言低级绘图函数-abline 转载
abline 函数的作用是在一张图表上添加直线, 可以是一条斜线,通过x或y轴的交点和斜率来确定位置:也可以是一条水平或者垂直的线,只需要指定与x轴或y轴交点的位置就可以了 常见用法: 1)添加直线 ...
- Miller_Rabin(米勒拉宾)素数测试算法
首先需要知道两个定理: 1: 费马小定理: 假如p是素数,且gcd(a,p)=1,那么 a(p-1)≡1(mod p). 2:二次探测定理:如果p是素数,x是小于p的正整数,且,那么要么x=1,要么x ...
- python 元组列表转为字典
#create a list l = [(), (), (), (), (), ()] d = {} for a, b in l: d.setdefault(a, []).append(b) prin ...
- Qt5_Oracle
1.编译驱动: 1.1.源码路径:F:\ZC_software_installDir\Qt5.3.2_vs2010\5.3\Src\qtbase\src\plugins\sqldrivers\ 里面有 ...
- css3转盘
此效果涉及到 : 1. css 画图形 2. css3 动态效果 3. 贝塞尔曲线 用法 <style> .lds-hourglass { display: inline-block; p ...
- robot 批处理文件
robot自带的ride工具不好用,就像填表格似的写脚本,太拘束.所以一直在用sublime text写robot脚本,但是也有问题:用sublime text写的脚本,只能运行一个文件的case,并 ...
- Python 爬虫-Scrapy爬虫框架
2017-07-29 17:50:29 Scrapy是一个快速功能强大的网络爬虫框架. Scrapy不是一个函数功能库,而是一个爬虫框架.爬虫框架是实现爬虫功能的一个软件结构和功能组件集合.爬虫框架是 ...
- Asp.Net MVC中Action跳转
首先action的跳转大致归类: 1跳转到与当前同一控制器内的action和不同控制器内的action. 2带有参数的action跳转和不带参数的action跳转. 3跳转到指定视图,不经过Contr ...