爬虫常见面试

本文详细介绍了Scrapy爬虫面试的常见问题,包括项目中遇到的反爬策略,Scrapy框架的选择及其优势,代理和验证码处理,模拟登录,分布式爬虫的工作原理和实现,以及Python基础、数据库和协议等相关知识点。通过实例讲解了Scrapy的去重机制、中间件使用、分布式判断和停止条件,深入探讨了数据存储、数据库选择,以及Python中的数据类型和编码方式。此外,还涵盖了HTTP协议、JSON数据提取和RESTful API设计。内容全面,是准备Scrapy面试的重要参考资料。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.项目问题:

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

  • 通过headers反爬虫:解决策略,伪造headers
  • 基于用户行为反爬虫:动态变化去爬取数据,模拟普通用户的行为, 使用IP代理池爬取或者降低抓取频率,或 通过动态更改代理ip来反爬虫
  • 基于动态页面的反爬虫:跟踪服务器发送的ajax请求,模拟ajax请求,selnium
    和phtamjs。或 使用selenium + phantomjs 进行抓取抓取动态数据,或者找到动态数据加载的json页面。
  • 验证码 :使用打码平台识别验证码
  • 数据加密:对部分数据进行加密的,可以使用selenium进行截图,使用python自带的pytesseract库进行识别,但是比较慢最直接的方法是找到加密的方法进行逆向推理。

2.你写爬虫的时候 使用的什么框架 选择这个框架的原因是什么?
scrapy。
优势:

  • 可以实现高并发的爬取数据, 注意使用代理;

  • 提供了一个爬虫任务管理界面, 可以实现爬虫的停止,启动,调试,支持定时爬取任务;

  • 代码简洁

    劣势:

  • 1.可扩展性不强。

  • 2.整体上来说: 一些结构性很强的, 定制性不高, 不需要太多自定义功能时用pyspider即可, 一些定制性高的,需要自定义一 些 功能时则使用Scrapy。

2.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整个流程了。
官方语言版本:
流程
1.引擎打开一个域名,蜘蛛处理这个域名,并让蜘蛛获取第一个爬取的URL。

2.引擎从蜘蛛那获取第一个需要爬取的URL,然后作为请求在调度中进行调度。

3.引擎从调度那获取接下来进行爬取的页面。

4.调度将下一个爬取的URL返回给引擎,引擎将他们通过下载中间件发送到下载器。

5.当网页被下载器下载完成以后,响应内容通过下载中间件被发送到引擎。

6.引擎收到下载器的响应并将它通过蜘蛛中间件发送到蜘蛛进行处理。

7.蜘蛛处理响应并返回爬取到的项目,然后给引擎发送新的请求。

8.引擎将抓取到的项目项目管道,并向调度发送请求。

系统重复第二步后面的操作,直到调度中没有请求,然后断开引擎与域之间的联系

4.scrapy的去重原理(指纹去重到底是什么原理)
在这里插入图片描述在这里插入图片描述

  • 需要将dont_filter设置为False开启去重,默认是False;
  • 对于每一个url的请求,调度器都会根据请求的相关信息加密得到一个指纹信息,并且将指纹信息和set()集合中得指纹信息进行比对,如果set()集合中已经存在这个数据,就不在将这个Request放入队列中。如果set()集合中没有,就将这个Request对象放入队列中,等待被调度。

5.scrapy中间件有几种类,你用过哪些中间件*
scrapy的中间件理论上有三种:

  • Schduler Middleware,

  • Spider Middleware,

  • Downloader Middleware),

  • 在应用上一般有以下两种:

    1.爬虫中间件Spider Middleware

    主要功能是在爬虫运行过程中进行一些处理.

    2.下载器中间件Downloader Middleware

    主要功能在请求到网页后,页面被下载时进行一些处理.
    使用
    1.Spider Middleware有以下几个函数被管理:
    process_spider_input 接收一个response对象并处理,

    位置是Downloader–>process_spider_input–>Spiders(Downloader和Spiders是scrapy官方结构图中的组件)
    process_spider_exception spider出现的异常时被调用
    process_spider_output 当Spider处理response返回result时,该方法被调用

    process_start_requests 当spider发出请求时,被调用
    位置是Spiders–>process_start_requests–>Scrapy Engine(Scrapy Engine是scrapy官方结构图中的组件)

2.Downloader Middleware有以下几个函数被管理

 - process_request  request通过下载中间件时,该方法被调

   

 - process_response 下载结果经过中间件时被此方法处理

  

 - process_exception 下载过程中出现异常时被调用

6.scrapy中间件再哪里起的作用

  • 1.爬虫中间件Spider Middleware:主要功能是在爬虫运行过程中进行一些处理.爬虫发起请求request的时候调用,列如更换修改代理ip,修改UA,

  • 2.下载器中间件Downloader Middleware:主要功能在请求到网页后,页面被下载时进行一些处理.浏览器返回响应response的时候调用,无效的数据,特殊情况进行重试

三.代理问题:

1.为什么会用到代理
一些网站会有相应的反爬虫措施,例如很多网站会检测某一段时间某个IP的访问次数,如果访问频率太快以至于看起来不像正常访客,它可能就会会禁止这个IP的访问。所以我们需要设置一些代理服务器,每隔一段时间换一个代理,就算IP被禁止,依然可以换个IP继续爬取。
2.代理怎么使用(具体代码, 请求在什么时候添加的代理)

1,可以使用urllib2中的ProxyHandler来设置代理ip

1 import urllib2
 2 
 3 # 构建了两个代理Handler,一个有代理IP,一个没有代理IP
 4 httpproxy_handler = urllib2.ProxyHandler({"http" : "124.88.67.81:80"})
 5 nullproxy_handler = urllib2.ProxyHandler({})
 6 #定义一个代理开关
 7 proxySwitch = True 
 8 # 通过 urllib2.build_opener()方法使用这些代理Handler对象,创建自定义opener对象
 9 # 根据代理开关是否打开,使用不同的代理模式
10 if proxySwitch:  
11     opener = urllib2.build_opener(httpproxy_handler)
12 else:
13     opener = urllib2.build_opener(nullproxy_handler)
14 
15 request = urllib2.Request("http://www.baidu.com/")
16 
17 # 使用opener.open()方法发送请求才使用自定义的代理,而urlopen()则不使用自定义代理。
18 response = opener.open(request)
19 
20 # 就是将opener应用到全局,之后所有的,不管是opener.open()还是urlopen() 发送请求,都将使用自定义代理。
21 # urllib2.install_opener(opener)
22 # response = urlopen(request)
23 
24 print response.read()

2,使用requets代理

 1 import requests
 2 
 3 # 根据协议类型,选择不同的代理
 4 proxies = {
 5   "http": "http://12.34.56.79:9527",
 6   "https": "http://12.34.56.79:9527",
 7 }
 8 
 9 response = requests.get("http://www.baidu.com", proxies = proxies)
10 print response.text

3.代理失效了怎么处理

事先用检测代码检测可用的代理,每隔一段时间更换一次代理,如果出现302等状态码,
则立即更换下一个可用的IP。
1 1、将代理IP及其协议载入ProxyHandler赋给一个opener_support变量;
2、将opener_support载入build_opener方法,创建opener;
3、安装opener。具体代码如下:from urllib import requestdef ProxySpider
(url, proxy_ip, header):opener_support =
 request.ProxyHa
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值