爬虫的基本面试

爬虫基本的面试题

  1. 在你的平时工作中,你在写爬虫的时候都遇到过什么样的反爬措施?你都是怎么解决它们的?

答:

  • Header:从用户的headers进行反爬是最常见的反爬虫策略.headers是一种区别浏览器星航和机器行为中最简单的方法,还有一些网站会对Referer(上级链接)进行检测(机器行为不太可能通过链接跳转实现)

    • 解决措施:通过审查元素或者开发者工具获取相对应的headers,然后把对应的headers传输给Python的requests,这样就能很好的绕过headers验证了
  • IP限制:一些网站会根据你的ip访问的频率,次数进行反爬.也就是说如果你用单一的IP地址访问频率过高,那么服务器会在短时间内禁止这个IP访问.

    • 解决措施:构造自己的IP代理池,然后每次访问时随机选择代理(但一些IP地址不是非常稳定,需要经常检查更新)
  • UA限制:UA是用户访问网站时候的标识,其反爬机制与ip限制类似.

    • 解决措施:使用随机UA
  • 验证码反爬虫或者模拟登录验证码:这个办法是相当古老并且相当的有效果,如果一个爬虫要解释一个验证码中的内容,这在以前通过简单的图像识别是可以完成的,但是就现在来讲,验证码的干扰线,噪点都很多,甚至还出现了人类都难以识别的验证码.

    • 解决措施:验证码识别的基本方法:截图二值化、中值滤波法去噪、分割、紧缩重排(让高矮统一)、字库特征匹配识别。(Python的PIL库或者其他),复杂的情况需求介入打码平台
  • Ajax动态加载:网页不希望被爬虫拿到数据使用Ajax动态加载,这样就为爬虫在成了绝大的麻烦,如果爬虫不具备js引擎,或者具备js引擎,不具备处理js返回的方案,或者是具备了js引擎,但是没办法让站点显示脚本的设置。基于这些情况,ajax动态加载反制爬虫还是相当有效的。

    • Ajax动态加载的工作原理是:从网页的url加载网页的源代码之后,会在浏览器里执行JavaScript程序。这些程序会加载出更多的内容,并把这些内容传输到网页中。这就是为什么有些网页直接爬它的url没有数据的原因。
    • 处理方法:找到对应的ajax接口,一半数据返回类型为json。
  • cookie限制:依次打开网页会生成一个随机cookie,如果再次打开网页这个cookie不存在,那么再次设置,第三次再打开还是没有,那就可能是爬虫再工作了。

    • 解决措施:在headers挂上相应的cookie或者根据其方法进行构造(例如从中选取几个字母进行构造)。如果过于复杂,可以考虑使用selenium模块(可以完全模拟浏览器行为)。
  1. 为什么会用到代理?

答:如果使用同一个ip不断的去访问的网站的话,会很容易被封ip,严重的永久封禁,导致当前的访问不了该网站。不只是通过程序,通过浏览器也无法访问。

  1. 在requests模块中,requests.content和requests.text什么区别?

答:requests.content获取的是字节,requests.text获取的是文本内容。

  1. 说一说进程、多线程和协程的区别?

答:

  • 进程:
    • 是具有一定独立功能的程序关于某个数据集合上的一次运行活动
    • 是系统进行资源分配和调度的一个独立单位。每一个进程都有自己的独立内存空间,不同进程通过进程间通信来通信。由于进程比较重量,占据独立的内存,所以上下文进程间的切换开销(栈、寄存器、虚拟内存、文件句柄等)比较大,但是相对比较稳定安全。
  • 线程:
    • 是进程的一个实体,是cpu调度和分派的基本的单位
    • 是比进程更小的能独立运行的基本单位
    • 线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈)。
    • 它可与同属于一个进程的其他的线程共享进程所拥有的的全部资源
    • 线程之间通信主要通过共享内存,上下文切换很快,资源开销较少,但是进程不够稳定容易丢失数据
  • 协程:
    • 是一种用户态的轻量级线程,协程的调度完全由用户控制。
    • 协程拥有自己的寄存器上下文和栈。
    • 协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈
    • 直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。
  • 区别:
    • 进程和线程比较:
      • 线程是指今后才能内的一个执行单元,也是进程内的可调度实体
    • 线程和进程的区别:
      • 地址空间:线程是进程内的一个执行单元,进程内至少有一个线程,他们共享进程的地址空间,而进程有自己独立的地址空间
      • 资源拥有:进程资源分配和拥有的单位,同一个进程内的线程共享进程的资源
      • 线程是处理器调度的基本单位,而进程不是
      • 二者均可并发执行
      • 每一个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口,但是线程不能够独立执行,必须已存在应用程序中,由应用程序提供多个线程执行控制
    • 协程与线程进行比较:
      • 一个线程可以多个协程,一个进程也可以单独拥有多个协程,这样Python中则能使用多核cpu。
      • 线程进程都是同步机制,而协程则是异步
      • 协程能保留上一次调用时的状态,每次过程重入时,就相当于上一次调用的状态
  1. 简要的介绍一下三次握手和四次挥手

答:

  • 三次握手:
    • 第一次握手:主机A发送同步报文段(SYN)请求建立连接
    • 第二次握手:主机B听到连接请求,就将该链接放入内核等待队列当中,并向主机A发送针对SYN的确认ACK,同时主机B也发送自己的请求建立连接(SYN)
    • 第三次握手:主机A针对主机BSYN的确认应答ACK
  • 四次挥手:
    • 第一次挥手:当主机A发送数据完毕后,发送FIN结束报文段。
    • 第二次挥手:主机B收到FIN报文段后,向主机发送一个确认序号ACK(为了防止在这段时间内,对方重传FIN报文段)。
    • 第三次挥手:主机B准备关闭连接,向主机A发送一个FIN结束报文段
    • 第四次挥手:主机A收到FIN结束报文段后,进入TIME_WAIT状态。并向主机B发送一个ACK表示连接彻底释放。
  • 除此之外经常看到的问题还有,为什么2、3次挥手不能何在一次挥手中?
    • 那是因为此时A虽然不在发送数据了,但是还是可以接受数据,B可能还有数据要发送给A,所以两次挥手不能合并为一次

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值