Python常见面试题四:爬虫和数据库部分

目录

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

2. 用过的爬虫框架或者模块有哪些?谈谈他们的区别或者优缺点?

3. 常用的 mysql 引擎有哪些?各引擎间有什么区别?

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

5. 什么是关联查询,有哪些?

6. 写爬虫是用多进程好?还是多线程好? 为什么?

7. 数据库的优化?

8. 常见的反爬虫和应对方法?

9. 分布式爬虫主要解决什么问题?

10. 爬虫过程中验证码怎么处理?


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

1) scrapy 是一个 Python 爬虫框架,爬取效率极高,具有高度定制性,但是不支持分布式。而 scrapy-redis 一套基于 redis 数据库、运行在 scrapy 框架之上的组件,可以让 scrapy 支持分布式策略,Slaver 端共享 Master 端 redis 数据库里的 item 队列、请求队列和请求指纹集合。

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

2. 用过的爬虫框架或者模块有哪些?谈谈他们的区别或者优缺点?

Python自带:urllib,urllib2

第三方:requests

框架:Scrapy

urllib 和 urllib2 模块都做与请求 URL 相关的操作,但他们提供不同的功能。

urllib2:urllib2.urlopen 可以接受一个 Request 对象或者url,(在接受 Request 对象时候,并以此可以来设置一个 URL 的headers),urllib.urlopen 只接收一个 url

urllib 有 urlencode,urllib2 没有,因此总是 urllib 与 urllib2 常会一起使用的原因

scrapy 是封装起来的框架,他包含了下载器,解析器,日志及异常处理,基于多线程, twisted 的方式处理,对于固定单个网站的爬取开发,有优势,但是对于多网站爬取 100个网站,并发及分布式处理方面,不够灵活,不便调整与括展。

request 是一个 HTTP 库, 它只是用来,进行请求,对于 HTTP 请求,他是一个强大的库,下载,解析全部自己处理,灵活性更高,高并发与分布式部署也非常灵活,对于功能可以更好实现.

Scrapy 优缺点:

优点:scrapy 是异步的

采取可读性更强的 xpath 代替正则

强大的统计和 log 系统

同时在不同的 url 上爬行

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

写 middleware,方便写一些统一的过滤器

通过管道的方式存入数据库

缺点:基于 python 的爬虫框架,扩展性比较差

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

3. 常用的 mysql 引擎有哪些?各引擎间有什么区别?

主要 MyISAM 与 InnoDB 两个引擎,其主要区别如下:

1). InnoDB 支持事务,MyISAM 不支持,这一点是非常之重要。事务是一种高级的处理方式,如在一些列增删改中只要哪个出错还可以回滚还原,而 MyISAM就不可以了;

2). MyISAM 适合查询以及插入为主的应用,InnoDB 适合频繁修改以及涉及到安全性较高的应用;

3). InnoDB 支持外键,MyISAM 不支持;

4). MyISAM 是默认引擎,InnoDB 需要指定;

5). InnoDB 不支持 FULLTEXT 类型的索引;

6). InnoDB 中不保存表的行数,如 select count(*) from table 时,InnoDB;需要扫描一遍整个表来计算有多少行,但是 MyISAM 只要简单的读出保存好的行数即可。注意的是,当 count(*) 语句包含 where 条件时 MyISAM 也需要扫描整个表;

7). 对于自增长的字段,InnoDB 中必须包含只有该字段的索引,但是在 MyISAM 表中可以和其他字段一起建立联合索引;

8). 清空整个表时,InnoDB 是一行一行的删除,效率非常慢。MyISAM 则会重建表;

9). InnoDB 支持行锁(某些情况下还是锁整表,如 update table set a = 1 where user like '%lee%'

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

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

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

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

5. 什么是关联查询,有哪些?

将多个表联合起来进行查询,主要有内连接、左连接、右连接、全连接(外连接)

6. 写爬虫是用多进程好?还是多线程好? 为什么?

IO密集型代码(文件处理、网络爬虫等),多线程能够有效提升效率(单线程下有IO操作会进行IO等待,造成不必要的时间浪费,而开启多线程能在线程A等待时,自动切换到线程B,可以不浪费CPU的资源,从而能提升程序执行效率)。在实际的数据采集过程中,既考虑网速和响应的问题,也需要考虑自身机器的硬件情况,来设置多进程或多线程

7. 数据库的优化?

1). 优化索引、SQL 语句、分析慢查询;

2). 设计表的时候严格根据数据库的设计范式来设计数据库;

3). 使用缓存,把经常访问到的数据而且不需要经常变化的数据放在缓存中,能节约磁盘IO;

4). 优化硬件;采用SSD,使用磁盘队列技术(RAID0,RAID1,RDID5)等;

5). 采用MySQL 内部自带的表分区技术,把数据分层不同的文件,能够提高磁盘的读取效率;

6). 垂直分表;把一些不经常读的数据放在一张表里,节约磁盘I/O;

7). 主从分离读写;采用主从复制把数据库的读操作和写入操作分离开来;

8). 分库分表分机器(数据量特别大),主要的的原理就是数据路由;

9). 选择合适的表引擎,参数上的优化;

10). 进行架构级别的缓存,静态化和分布式;

11). 不采用全文索引;

12). 采用更快的存储方式,例如 NoSQL存储经常访问的数据

8. 常见的反爬虫和应对方法?

1). 通过Headers反爬虫

从用户请求的Headers反爬虫是最常见的反爬虫策略。很多网站都会对Headers的User-Agent进行检测,还有一部分网站会对Referer进行检测(一些资源网站的防盗链就是检测Referer)。如果遇到了这类反爬虫机制,可以直接在爬虫中添加Headers,将浏览器的User-Agent复制到爬虫的Headers中;或者将Referer值修改为目标网站域名。对于检测Headers的反爬虫,在爬虫中修改或者添加Headers就能很好的绕过。

2). 基于用户行为反爬虫

还有一部分网站是通过检测用户行为,例如同一 IP 短时间内多次访问同一页面,或者同一账户短时间内多次进行相同操作。

大多数网站都是前一种情况,对于这种情况,使用 IP 代理就可以解决。可以专门写一个爬虫,爬取网上公开的代理 ip,检测后全部保存起来。这样的代理 ip 爬虫经常会用到,最好自己准备一个。有了大量代理ip后可以每请求几次更换一个 ip,这在requests 或者 urllib2 中很容易做到,这样就能很容易的绕过第一种反爬虫。

对于第二种情况,可以在每次请求后随机间隔几秒再进行下一次请求。有些有逻辑漏洞的网站,可以通过请求几次,退出登录,重新登录,继续请求来绕过同一账号短时间内不能多次进行相同请求的限制。

3). 动态页面的反爬虫

上述的几种情况大多都是出现在静态页面,还有一部分网站,我们需要爬取的数据是通过 ajax 请求得到,或者通过 JavaScript 生成的。首先用 Fiddler 对网络请求进行分析。如果能够找到 ajax 请求,也能分析出具体的参数和响应的具体含义,我们就能采用上面的方法,直接利用 requests 或者 urllib2 模拟 ajax 请求,对响应的 json 进行分析得到需要的数据。

能够直接模拟 ajax 请求获取数据固然是极好的,但是有些网站把 ajax 请求的所有参数全部加密了。我们根本没办法构造自己所需要的数据的请求。这种情况下就用 selenium + phantomJS,调用浏览器内核,并利用 phantomJS 执行 js 来模拟人为操作以及触发页面中的 js 脚本。从填写表单到点击按钮再到滚动页面,全部都可以模拟,不考虑具体的请求和响应过程,只是完完整整的把人浏览页面获取数据的过程模拟一遍。

用这套框架几乎能绕过大多数的反爬虫,因为它不是在伪装成浏览器来获取数据(上述的通过添加 Headers 一定程度上就是为了伪装成浏览器),它本身就是浏览器,phantomJS 就是一个没有界面的浏览器,只是操控这个浏览器的不是人。利 selenium + phantomJS 能干很多事情,例如识别点触式(12306)或者滑动式的验证码,对页面表单进行暴力破解等。

9. 分布式爬虫主要解决什么问题?

1). ip

2). 带宽

3). cpu

4). io

10. 爬虫过程中验证码怎么处理?

1). scrapy自带

2). 付费接口

文章来源

你可能感兴趣的:(Python面试合辑)