python爬虫面试题

1.你写爬虫的时候都遇到过什么?反爬虫措施,你是怎么解决的?

  1. 通过headers反爬虫;
  2. 基于用户行为的发爬虫:(同一IP短时间内访问的频率);
  3. 动态网页反爬虫(通过ajax请求数据,或者通过JavaScript生成);

解决途径:

  1. 对于基本网页的抓取可以自定义headers,将header随request一起发送(一般是User-Agent,Cookie)
  2. 使用IP代理池爬取或者降低抓取频率
  3. 使用selenium + phantomjs 进行抓取抓取动态数据,或者找到动态数据加载的json页面

2.用的什么框架,为什么选择这个框架?

scrapy是一个功能非常强大的爬虫框架,它不仅能便捷地构建request,还有强大的selector能够方便地解析response,然而它最受欢迎的还是它的性能,即抓取和解析的速度,它的downloader是多线程的,request是异步调度和处理的。这两点使它的爬取速度非常之快。另外还有内置的logging,exception,shell等模块,为爬取工作带来了很多便利。

以下关于scrapy的问题:

1.scrapy的基本结构(五个部分)都是什么?,请求发出去的整个流程?

scrapy由Spider、Engine、Scheduler、Downloader、Item Pipline五个部分组成。发送请求主要由如下几个步骤:

  1. 首先Spiders(爬虫)将需要发送请求的url(requests)到Engine(引擎)。
  2. Engine(引擎)把request交给Scheduler(调度器)。
  3. Scheduler经过排序,入队处理后,重新把request发送到Engine。
  4. Engine把request请求通过DownloaderMiddlewares(可选,主要有User_Agent, Proxy代理)交给Downloader(下载器)。
  5. Downloader向网站发送请求,并接受下载响应(Response),将Response返回给Engine。
  6. Response由Engine,经过SpiderMiddlewares(可选)发送到Spiders开始解析。
  7. 解析数据完成后,将所需的Items原路返回到Engine。
  8. Engine将Items发送到ItemPipeline(可以是本地,可以是数据库),提取下一个url再次进行循环。

2.scrapy的去重原理 (指纹去重到底是什么原理)

对于每一个url的请求,调度器都会根据请求得相关信息加密得到一个指纹信息,并且将指纹信息和set()集合中的指纹信息进行比对,如果set()集合中已经存在这个数据,就不在将这个Request放入队列中。如果set()集合中没有存在这个加密后的数据,就将这个Request对象放入队列中,等待被调度。

3.scrapy中间件有几种类,你用过那些中间件(详情

scrapy中间件有Spider Middlewares 和 Downloader Middlewares两种(中间件原理),将fake-useragent和IP代理集成到Middlewares中,使Spider在发送request时主动更换User-Agent和IP。

4.scrapy中间件在哪里起的作用(面向切面编程)

1.爬虫中间件Spider Middleware:主要功能是在爬虫运行过程中进行一些处理.

2.下载器中间件Downloader Middleware:主要功能在请求到网页后,页面被下载时进行一些处理.

代理问题

1.为什么会用到代理?

网站的反爬虫策略会检测到同一个IP访问次数频率过快,从而禁止该IP的访问。因此爬虫过程中需要IP代理避免该问题。

2.代理怎么使用(具体代码,请求在什么时候添加的代理)

class RandomProxyMiddleware(object):
    #动态设置ip代理
    def process_request(self, request, spider):
        get_ip = GetIP()    #GetIP是获取代理IP的方法
        request.meta["proxy"] = get_ip.get_random_ip()

该方法需要在Spider Middlewares中添加,为了在给网站发送请求前获得有效的代理IP。

3.代理失效了怎么处理?

事先用检测代码检测可用的代理,每隔一段时间更换一次代理,如果出现302等状态码,则立即更换下一个可用的IP。

四.验证码处理

1.登陆验证码处理

  1. 图片验证码:先将验证码图片下载到本地,然后使用云打码识别;
  2. 滑动验证码:使用selenium模拟人工拖动,对比验证图片的像素差异,找到滑动的位置然后获取它的location和size,然后 top,bottom,left,right = location['y'] ,location['y']+size['height']+ location['x'] + size['width']  ,然后截图,最后抠图填入这四个位置就行。

2.爬取速度过快出现的验证码处理

  1. 设置setting.py中的DOWNLOAD_DELAY,降低爬取速度;

  2. 用xpath获取验证码关键字,当出现验证码时,识别验证码后再继续运行。

3.如何用机器识别验证码

模拟登陆问题

1.模拟登陆流程

  1. 加载浏览器driver;
  2. 获取登录页面;
  3. 使用css选择器或者xpath找到账号和密码输入框,并发送账号和密码;
  4. 如果出现验证码则需要先识别验证码,在模拟输入验证码或者模拟鼠标拖动;
  5. 使用css选择器或者xpath找到登录按钮,使用click模拟点击;

2.cookie如何处理

  1.  采用selenium自动登录获取cookie,保存到文件;
  2. 读取cookie,比较cookie的有效期,若过期则再次执行步骤1;
  3. 在请求其他网页时,填入cookie,实现登录状态的保持;

3.如何处理网站传参加密的情况

加密的三种情况:

  1. 加密+访问次数限制+每个页面相关信息的条目需要点详情进行二次请求;
  2. 复杂的加密算法进行参数+时间戳+sig值,后台进行 参数+时间限制;
  3. 定时同步cookie+每个界面一个cookie。

破解方法:

  1. 使用selenium模拟点击获取详情页面;
  2. 获取其相应的api接口,GET接口URL,获取它的json表格内容;
  3. 反向分析网页JS加载内容;

六.分布式

1.分布式原理

分布式爬虫主要由主机与从机,我们把自己的核心服务器(主机)称为 master,而把用于跑爬虫程序的机器(从机)称为 slave。

我们首先给爬虫一些start_urls,spider 最先访问 start_urls 里面的 url,再根据我们的 parse 函数,对里面的元素、或者是其他的二级、三级页面进行抓取。而要实现分布式,只需要在这个starts_urls里面做文章就行了。进一步描述如下:

  1. master 产生 starts_urls,url 会被封装成 request 放到 redis 中的 spider:requests,总的 scheduler 会从这里分配 request,当这里的 request 分配完后,会继续分配 start_urls 里的 url。
  2. slave 从 master 的 redis 中取出待抓取的 request,下载完网页之后就把网页的内容发送回 master 的 redis,key 是 spider:items。scrapy 可以通过 settings 来让 spider 爬取结束之后不自动关闭,而是不断的去询问队列里有没有新的 url,如果有新的 url,那么继续获取 url 并进行爬取,所以这一过程将不断循环。
  3. master 里的 reids 还有一个 key 是 “spider:dupefilter” 用来存储抓取过的 url 的 fingerprint(使用哈希函数将url运算后的结果),防止重复抓取,只要 redis 不清空,就可以进行断点续爬。

2.分布式如何判断爬虫已经停止了

3.分布式去重原理

可以用布隆过滤器(Bloom filiter)进行去重。

七.数据存储和数据库问题

1.关系型数据库和非关系型数据库的区别

https://blog.csdn.net/longxingzhiwen/article/details/53896702

2.爬下来数据你会选择什么存储方式,为什么

3.各种数据库支持的数据类型,和特点,比如:redis如何实现持久化,mongodb是否支持事物等。。

https://blog.csdn.net/hzp666/article/details/79168675

八.python基础问题

1.python2和python3的区别,如何实现python2代码迁移到python3环境

区别:字符串类型、默认字符、print方法、除法的数字类型、导入方式、继承类、元类声明、异常处理、字典、模块合并、部分模块重命名(详情

代码迁移:python3有个内部工具叫做2to3.py,位置在Python3/tool/script文件夹。

首先CD到这个文件夹,然后调用

py 2to3.py -w f:/xxxx/xxx.py

使用方法

2.python2和python3的编码方式有什么差别?

在python2中主要有str和unicode两种字符串类型,而到python3中改为了bytes和str,并且一个很重要的分别是,在python2中如果字符串是ascii码的话,str和unicode是可以直接进行连接和比较,但是到python3中就不行了,bytes和str是两个独立的类型。另一个重要的是python2中不管是str还是unicode都可以直接写入文件,而不需要加上它是不是str的类型写入方式,但是在python3中如果是写或者读bytes类型就必需带上’b’.

3.迭代器,生成器,装饰器

https://blog.csdn.net/hduxiejun/article/details/60470058

4.python的数据类型

https://www.cnblogs.com/fengzheng/p/3590891.html

九.协议问题

1.http协议,请求由什么组成,每个字段分别有什么用,https和http有什么差距?

请求行(request line)、请求头部(header)、空行和请求数据四个部分组成(详情);

  1. 请求行,用来说明请求类型,要访问的资源以及所使用的HTTP版本;
  2. 请求头部,紧接着请求行(即第一行)之后的部分,用来说明服务器要使用的附加信息;
  3. 空行,请求头部后面的空行是必须的;
  4. 请求数据也叫主体,可以添加任意的其他数据;

 HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全,为了保证这些隐私数据能加密传输,于是网景公司设计了SSL(Secure Sockets Layer)协议用于对HTTP协议传输的数据进行加密,从而就诞生了HTTPS。简单来说,HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。

  HTTPS和HTTP的区别主要如下:

  1. https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
  2. http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
  3. http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
  4. http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

2.证书问题

https://blog.csdn.net/fangqun663775/article/details/55189107

3.TCP,UDP各种相关问题

https://blog.csdn.net/xiaobangkuaipao/article/details/76793702

十.数据提取问题

1.主要使用什么样的结构化数据提取方式(详情)?

JSON文件

  • JSON Path
  • 转化为Python类型进行操作(json类)

XML文件

  • 转化为Python类型(xmltodict)
  • XPath
  • CSS选择器
  • 正则表达式

2.正则的使用

参考:http://tool.oschina.net/uploads/apidocs/jquery/regexp.html

3.动态加载的数据如何提取?

  1. selenium获取;
  2. 分析请求页面,获取它的js请求文件;

4.json数据如何提取

  1. 采用正则表达式解析:获取整个json数据后,采用正则表达式匹配到关键词;
  2. 基于json格式进行获取:json的数据格式与python的dict是有极大的类似之处。在python的 json 这个包里面提供了两个经典的预处理方法:json.dumps:ptyhondict转成strjson.loads:将str转成pythondict类型;

 

---

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值