爬虫基本面试题

 

  1. 你用过的Python爬虫模型或框架有哪些?各有什么优缺点?

    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请求,他是一个强大的库,下载,解析全部自己处理,灵活性更高,高并发与分布式部署也非常灵活,对于功能可以更好实现.

     2,scrapy和scrapy-redis的区别?

       scrapy是一个爬虫通用框架,但不支持分布式,scrapy-redis是为了更方便的实现scrapy分布式爬虫,而提供了一些以redis为基础的组件

        为什么会选择redis数据库?

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

        什么是主从同步?

    在Redis中,用户可以通过执行SLAVEOF命令或者设置slaveof选项,让一个服务器去复制(replicate)另一个服务器,我们称呼被复制的服务器为主服务器(master),而对主服务器进行复制的服务器则被称为从服务器(slave),当客户端向从服务器发送SLAVEOF命令,要求从服务器复制主服务器时,从服务器首先需要执行同步操作,也即是,将从服务器的数据库状态更新至主服务器当前所处的数据库状态

    3,scrapy的优缺点?为什么要选择scrapy框架?

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

    强大的统计和log系统 

    同时在不同的url上爬行 

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

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

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

    缺点:基于python爬虫框架,扩展性比较差,基于twisted框架,运行中exception是不会干掉reactor,并且异步框架出错后是不会停掉其他任务的,数据出错后难以察觉

    4,scrapy和requests的使用情况?

    requests 是 polling 方式的,会被网络阻塞,不适合爬取大量数据

    scapy 底层是异步框架 twisted ,并发是最大优势

    5,描述一下scrapy框架的运行机制?

    从start_urls里面获取第一批url发送请求,请求由请求引擎给调度器入请求对列,获取完毕后,调度器将请求对列交给下载器去获取请求对应的响应资源,并将响应交给自己编写的解析方法做提取处理,如果提取出需要的数据,则交给管道处理,如果提取出url,则继续执行之前的步骤,直到多列里没有请求,程序结束。

    6,写爬虫使用多进程好,还是用多线程好?

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

    7,常见的反爬虫和应对方法?

        1. 基于用户行为,同一个ip段时间多次访问同一页面

            利用代理ip,构建ip池

        2. 请求头里的user-agent

            构建user-agent池(操作系统、浏览器不同,模拟不同用户)

        3. 动态加载(抓到的数据和浏览器显示的不一样),js渲染

        模拟ajax请求,返回json形式的数据

        4,selenium / webdriver 模拟浏览器加载

        5,对抓到的数据进行分析

        6,加密参数字段

         会话跟踪【cookie】

          防盗链设置【Referer

    8,分布式爬虫主要解决什么问题?

            面对海量待抓取网页,只有采用分布式架构,才有可能在较短时间内完成一轮抓取工作。

            它的开发效率是比较快而且简单的。

    9,爬取时弹出对话框让验证,又该怎么处理?

        HTTP请求的basic认证

    客户端将输入的用户名密码用Base64进行编码后,采用非加密的明文方式传送给服务器。

    Authorization: Basic xxxxxxxxxx.

    10,你在爬虫过程中,都是怎么解决反爬的,爬取多少数据,用了多长时间?

    11,爬取这些数据都用来做什么的?怎么交付给公司?客户是谁?爬取数据的影响因素?

        当时我们公司核心业务是网站开发,还有数据的采集,会经常需要一些数据,采集的数据一 是为了满足公司需求,二是我们有合作的公司,负责给他们提供他们所需要的数据,(根据客户需求做好 相应格式的数据文件,交付给项目组长)(数据库导出)

        影响因素:机器的性能及带宽,代码质量,爬取时的反爬机制

    12,什么是爬虫,为什么要用爬虫?

        用于在网络上采集数据的程序,可以用任何语言开发,python更加方便快捷高效一些。

        爬虫的目的:采集一些需要的数据。

        为什么python更适合写爬虫程序?python中封装了很多爬虫库,如urllib ,re,bs,scrapy等,开发效率更高

    13,爬虫的基本流程?

            1,浏览器发起请求,可能包含请求头等信息,等待服务器相应

             2,获取服务器响应内容,可能是网页文本(html、json代码),图片二进制、视频二进制等

            3,解析内容(正则、xpath、json解析等 )

            4, 保存数据(本地文件、数据库等)

    14,如何提高爬取效率?

            爬虫下载慢主要原因是阻塞等待发往网站的请求和网站返回

            1,采用异步与多线程,扩大电脑的cpu利用率;

            2,采用消息队列模式

            3,提高带宽

    15,request请求方式中的post、get有什么区别

         GET一般用于获取/查询资源信息,而POST一般用于更新资源信息

        get是在url中传递数据,数据放在请求头中,post是在请求体中传递数据

        get安全性非常低,post安全性较高,但是get执行效率却比Post方法好

    16,模拟登陆原理?

        因为http请求是无状态的,网站为了识别用户身份,需要通过cookie记录用户信息(用户、密码),这些信息都会在手动登陆时记录在post请求的form-data里,那么在爬虫时候只需要将这些信息添加到请求头里即可。

    17,分布式原理?

    多台机器多个spider 对多个 url 同时进行处理

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

    18,下载器中间件(Downloader Middlewares)

    位于Scrapy引擎和下载器之间的框架,主要是处理Scrapy引擎与下载器之间的请求及响应。

    爬虫中间件(Spider Middlewares)介于Scrapy引擎和爬虫之间的框架,主要工作是处理蜘蛛的响应输入和请求输出。

    调度中间件(Scheduler Middewares)介于Scrapy引擎和调度之间的中间件,从Scrapy引擎发送到调度的请求和响应

    19,爬虫协议?

    Robots协议(也称为爬虫协议、爬虫规则、机器人协议等)也就是robots.txt,网站通过robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取。

    Robots协议是网站国际互联网界通行的道德规范,其目的是保护网站数据和敏感信息、确保用户个人信息和隐私不被侵犯。因其不是命令,故需要搜索引擎自觉遵守。

    20,爬虫的底层原理?

    21,scrapy中间件有几种类,你用过那些中间件?

            scrapy的中间件理论上有三种(Schduler Middleware,Spider Middleware,Downloader Middleware)

    DownloaderMiddleware主要处理请求Request发出去和结果Response返回的一些回调,

    比如说你要加UserAgent,使用代理,修改refferer(防盗链),添加cookie,或者请求异常超时处理啥的

            常用: 1.爬虫中间件Spider Middleware

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

      2.下载器中间件Downloader Middleware

             主要功能在请求到网页后,页面被下载时进行一些处理.

    22,代理问题

    1.为什么会用到代理

    将真是IP隐藏起来(请求过于太频繁的话,ip可能会被禁止)

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

    proxy_handler = ProxyHandler({'http': 'http://183.159.89.204:18118'})

    # 构建一个Opener对象

    proxy_opener = build_opener(proxy_handler)

    # 使用自定义opener访问服务器数据,得到相应

    response = proxy_opener.open(request)

    3.代理失效了怎么处理

    23,验证码处理

    1.登陆验证码处理

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

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

    24,模拟登陆问题

    1.模拟登陆流程

    因为http请求是无状态的,网站为了识别用户身份,需要通过cookie记录用户信息(用户、密码),这些信息都会在手动登陆时记录在post请求的form-data里,那么在爬虫时候只需要将这些信息添加到请求头里即可

    2.cookie如何处理

    同上

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

    对抓包数据进行分析,这要 在具体的项目中去说明

    25,数据存储和数据库问题

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

                    1.关系型数据库通过外键关联来建立表与表之间的关系,

                    2.非关系型数据库通常指数据以对象的形式存储在数据库中,而对象之间的关系通过每个对象自身的属性来决定

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

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

    是否支持事物等 。。

    26,协议问题

    # 爬虫从网页上拿数据肯定需要模拟网络通信的协议

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

    2.证书问题

    3.TCP,UDP各种相关问题

    27,数据提取问题

    1.主要使用什么样的结构化数据提取方式

        xpath  正则  bs4等

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

    模拟ajax请求,返回json形式的数据

    3.json数据如何提取

        python中内置了json模块,提供了dumps、dump、loads、load,用于字符串 和 python数据类型间进行转换。然后再对数据用递归,正则,或者一层一层获取的方法得到数据

    28,redis数据库有哪几种数据结构?

    5种数据结构:

       String字符串

    List列表

    Set集合

    Hash散列

    Zset有序集合

    29,使用redis搭建分布式系统时如何处理网络延迟和网络异常?

    由于网络异常的存在,分布式系统中请求结果存在“三态”的概念,即三种状态:“成功”、“失败”、“超时(未知)”

    当出现“超时”时可以通过发起读取数据的操作以验证 RPC 是否成功(例如银行系统的做法)

    另一种简单的做法是,设计分布式协议时将执行步骤设计为可重试的,即具有所谓的“幂等性”

    也可设置一个超时时间,如果超过该时间,可以try出去。

    30,如果对方网站反爬取,封IP了怎么办?

    1,放慢抓取熟速度,减小对目标网站造成的压力,但是这样会减少单位时间内的数据抓取量

    2,使用代理IP(免费的可能不稳定,收费的可能不划算)

     

    31,关于防盗链?

    部分服务器会检查 http 请求头的 Referer 字段来判断你是否是从指定页面跳转而来的,以达到防盗链的作用。因此在伪装请求头部的时候,该字段也是不容忽视的。

    1.  

      32,对__if__name__ == 'main'的理解陈述

      __name__是当前模块名,当模块被直接运行时模块名为_main_,也就是当前的模块,当模块被导入时,模块名就不是__main__,即代码将不会执行。

      33Python里面如何拷贝一个对象?(赋值,浅拷贝,深拷贝的区别)

      赋值(=),就是创建了对象的一个新的引用,修改其中任意一个变量都会影响到另一个。
      浅拷贝:创建一个新的对象,但它包含的是对原始对象中包含项的引用(如果用引用的方式修改其中一个对象,另外一个也会修改改变){1,完全切片方法;2,工厂函数,如list();3,copy模块的copy()函数}
      深拷贝:创建一个新的对象,并且递归的复制它所包含的对象(修改其中一个,另外一个不会改变){copy模块的deep.deepcopy()函数

       

    try…except…except…else…
    执行try下的语句,如果引发异常,则执行过程会跳到except语句。对每个except分支顺序尝试执行,如果引发的异常与except中的异常组匹配,执行相应的语句。如果所有的except都不匹配,则异常会传递到下一个调用本代码的最高层try代码中。
    try下的语句正常执行,则执行else块代码。如果发生异常,就不会执行如果存在finally语句,最后总是会执行。

    35、Python中__new__与__init方法的区别

    __new__:它是创建对象时调用,会返回当前对象的一个实例,可以用_new_来实现单例 

    __init__:它是创建对象后调用,对当前对象的一些实例初始化,无返回值

    36. 常用的网络数据爬取方法

    • 正则表达式

    • Beautiful Soup

    • Lxml

    37、遇到过得反爬虫策略以及解决方法

    1.通过headers反爬虫
    2.基于用户行为的发爬虫:(同一IP短时间内访问的频率)
    3.动态网页反爬虫(通过ajax请求数据,或者通过JavaScript生成)
    4.对部分数据进行加密处理的(数据是乱码)
    解决方法:
    对于基本网页的抓取可以自定义headers,添加headers的数据
    使用多个代理ip进行抓取或者设置抓取的频率降低一些,
    动态网页的可以使用selenium + phantomjs 进行抓取
    对部分数据进行加密的,可以使用selenium进行截图,使用python自带的pytesseract库进行识别,但是比较慢最直接的方法是找到加密的方法进行逆向推理。

    38、urllib 和 urllib2 的区别

    urllib 和urllib2都是接受URL请求的相关模块,但是urllib2可以接受一个Request类的实例来设置URL请求的headers,urllib仅可以接受URL。urllib不可以伪装你的User-Agent字符串。
    urllib提供urlencode()方法用来GET查询字符串的产生,而urllib2没有。这是为何urllib常和urllib2一起使用的原因。

     

    39、列举网络爬虫所用到的网络数据包,解析包

    • 网络数据包 urllib、urllib2、requests

    • 解析包 re、xpath、beautiful soup、lxml

    40、POST与 GET的区别

    • GET数据传输安全性低,POST传输数据安全性高,因为参数不会被保存在浏览器历史或web服务器日志中;

    • 在做数据查询时,建议用GET方式;而在做数据添加、修改或删除时,建议用POST方式;

    • GET在url中传递数据,数据信息放在请求头中;而POST请求信息放在请求体中进行传递数据;

    • GET传输数据的数据量较小,只能在请求头中发送数据,而POST传输数据信息比较大,一般不受限制;

    • 在执行效率来说,GET比POST好

    41、什么是lambda函数?它有什么好处?

    lambda 表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数
    lambda函数:首要用途是指点短小的回调函数

    42. 介绍一下except的用法和作用?

  2. try…except…except…[else…][finally…]

    执行try下的语句,如果引发异常,则执行过程会跳到except语句。对每个except分支顺序尝试执行,如果引发的异常与except中的异常组匹配,执行相应的语句。如果所有的except都不匹配,则异常会传递到下一个调用本代码的最高层try代码中。

    try下的语句正常执行,则执行else块代码。如果发生异常,就不会执行

    如果存在finally语句,最后总是会执行

     

    except: #捕获所有异常


    except: <异常名>: #捕获指定异常


    except:<异常名 1, 异常名 2> : 捕获异常 1 或者异常 2


    except:<异常名>,<数据>:捕获指定异常及其附加的数据


    except:<异常名 1,异常名 2>:<数据>:捕获异常名 1 或者异常名 2,及附加的数据

答:pass语句不会执行任何操作,一般作为占位符或者创建占位程序,whileFalse:pass

44.介绍一下Python下range()函数的用法?

答:列出一组数据,经常用在for in range()循环中

 45.Python里面如何生成随机数?

答:random模块

随机整数:random.randint(a,b):返回随机整数x,a<=x<=b

random.randrange(start,stop,[,step]):返回一个范围在(start,stop,step)之间的随机整数,不包括结束值。

随机实数:random.random( ):返回0到1之间的浮点数

random.uniform(a,b):返回指定范围内的浮点数。

46.有没有一个工具可以帮助查找python的bug和进行静态的代码分析?

答:PyChecker是一个python代码的静态分析工具,它可以帮助查找python代码的bug, 会对代码的复杂度和格式提出警告

Pylint是另外一个工具可以进行codingstandard检查

47.如何在一个function里面设置一个全局的变量?

答:解决方法是在function的开始插入一个global声明:

def f()

global x

  1.  

    1. last:爬虫中遇到的错误,是怎么解决的?

    2. 1,获取json数据之后,把Json格式字符串解码转换成Python对象时,在json.loads的时候出错?

          要注意被解码的Json字符的编码,如果传入的字符串的编码不是UTF-8的话,需要指定字符编码的参数encoding

      2,使用urllib2时,经常遇到编码问题

      3,有时会遇到503错误

          主要是指服务器判断出你是爬虫程序,所以需要改变一下请求头,设置一下时间的间隔

      4,bs4库解析时遇到的问题?

      html 页面的数据经过Beautiful Soup库的解析后,部分html源码丢失,找不到想要的数据了

      查看官方文档,bs 库支持的解析库有 lxml, html5lib 和 html.parser。用的最多的是 lxml,因为它的解析速度快,并且容错能力强,默认也是使用该解析器。

      出现解析后源码丢失的可能原因有 2 个:

      BeautifulSoup 有时候会遇到非法的,不支持的 html 源码而导致无法解析或无法正常解析 html;

      处理的文档太大,而处理的解析器缓存不够造成的信息丢失。

      这里换一个解析器,换成 html.parser 就可以了。


       

      摘自:城北有梦https://www.jianshu.com/p/db9046b58173

    3.         hurt-  https://blog.csdn.net/weixin_40907382/article/details/80480675

    4.    hackerie  https://blog.csdn.net/hackerie/article/details/79077634

你可能感兴趣的:(求职面试)