2020年Python最新面试题(四):爬虫基础知识

目录

1. 什么是爬虫?

网络爬虫 (又被称为网页蜘蛛,网络机器人或网页追逐者),是一种按照指定规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫等,网络爬虫简称爬虫。

爬虫通俗地讲就是通过程序去获取 Web 页面上自己想要的数据,也就是自动抓取网页数据的程序。一般来说,只要能通过浏览器访问的数据都可以通过爬虫获取到。爬虫的本质:就是模拟浏览器打开网页,然后获取网页中所需要的那部分数据。

浏览器打开网页的过程包括:当在浏览器中输入地址后,经过 DNS 服务器查找到服务器主机,向服务器发送一个请求,服务器经过解析后再返还给用户浏览器结果,包括 html、js、css 等文件内容,在浏览器解析这些数据后,最终呈现给用户,即用户在浏览器上看到的结果。所以用户看到的浏览器的结果就是由 html 代码构成的。爬虫就是为了获取这些内容,通过分析和过滤 html 代码,从中获取想要的文本、图片及视频等资源。

2. 爬虫的基本流程有哪些?

可以分为以下几个流程:

(1) 发起请求,通过 HTTP 库向目标站点发起请求,即发送一个 Request,请求可以包含额外的 Header 等信息,等待服务器响应。
(2) 获取响应内容:如果服务器能够正常响应,会得到一个 Response,Response 的内容便是所要获取的页面内容,类型可能是 Html、Json 字符串、二进制数据 (图片或者视频) 等类型。
(3) 解析内容:如果得到的是 Html,可以使用正则表达式、页面解析库进行解析。如果是 Json,可以直接转换为 Json 对象解析。如果是二进制数据 (图片或者视频),可以保存或者进一步的处理。
(4) 保存数据:保存形式多样,可以存为文本,也可以保存到数据库,或者保存特定格式的文件。

3. Request 中包含了哪些内容?

(1) 请求方式:请求主要有 GET 和 POST 两种类型,另外还有 HEAD、PUT、DELETE 及 OPTIONS 等请求方式。

GET:向指定的资源发出显示请求。使用 GET 方法只用于读取数据,而不应当被用于产生副作用的操作中,其中一个原因是 GET 可能会被网络蜘蛛等随意访问。
POST:向指定资源提交数据,请求服务器进行处理 (例如提交表单或者上传文件)。数据被包含在请求文本中。这个请求可能会创建新的资源或修改现有资源,或二者皆可。

(2) 请求URL (Uniform Resource Locator) 即统一资源定位符,也就是大家常见的网址。统一资源定位符是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的 URL,它包含的信息有文件的位置以及浏览器应该怎么处理它。URL 的格式由三个部分组成:

第一部分是协议 (或称为服务方式)。
第二部分是存有该资源的主机 IP 地址(有时也包括端口号)。
第三部分是主机资源的具体地址,如目录和文件名等。
爬虫爬取数据时必须要有一个目标 URL 才可以获取数据,因此,它是爬虫获取数据的基础。

(3) 请求头:包含请求时的头部信息,例如,Accept、Accept-Encoding、Accept-Language、Connection、User-Agent、Host、Referer、Cookies 等信息。详解见下表:

在这里插入图片描述
在这里插入图片描述
(4) 请求体:请求是携带的数据,如提交表单数据时候的表单数据 (POST)。下图为百度主页的访问请求的 Request 内容:

在这里插入图片描述

4. Response 中包含了哪些内容

所有 HTTP 响应的第一行都是状态行,依次是当前 HTTP 版本号,3位数字组成的状态代码,以及描述状态的短语,彼此由空格分隔。

(1) 响应状态:有多种响应状态,如:200 代表成功,301 跳转,404 找不到页面,502 服务器错误。
(2) 响应头:如内容类型、类型的长度、服务器信息、设置 Cookie 等。
(3) 响应体:最主要的部分,包含请求资源的内容,如网页 HTML、图片和二进制数据等。下图为百度主页的访问请求的 Response 内容:

在这里插入图片描述

5. HTTP 请求中的 POST、GET 有什么区别?

区别主要有以下几点:

(1) GET 请求是通过 URL 直接传递请求数据,数据信息可以在 URL 中直接看到,例如在浏览器访问的时候,在 URL 中可以看到 GET 请求的参数,而 POST 请求是放在请求头中的,用户无法直接看到请求的参数。
(2) GET 提交有数据大小的限制,一般是不超过 1024B,而这种说法也不完全准确,HTTP 协议并没有设定 URL 字节长度的上限,而是浏览器做了些处理,所以长度依据浏览器的不同有所不同。POST 请求在 HTTP 协议中也没有做说明,一般来说是没有设置限制的,但是实际上浏览器也有默认值。总体来说,少量的数据使用 GET,大量的数据使用 POST。
(3) GET 请求因为数据参数是暴露在 URL 中的,所以安全性较低,例如密码是不能透露的,就不能使用 GET 请求;POST 请求中,请求参数信息是放在请求头的,所以安全性较高。在实际使用的时候,涉及登录操作的时候,尽量使用 POST 请求,因为 POST 的安全性更好。GET 请求执行效率却比 POST 请求好。

建议:

(1) GET 方式的安全性较 POST 方式要差些,如果包含机密信息的话,那么建议用 POST 数据提交方式。
(2) 在做数据查询时,建议用 GET 方式;而在做数据添加、修改或删除时,建议用 POST 方式。

6. HTTP、HTTPS 协议有什么区别?

HTTP 协议是超文本传输协议,被用于在 Web 浏览器和网站服务器之间传递信息。HTTP 协议是以明文方式发送内容的,不提供任何形式的数据加密,而这也是很容易被黑客利用的地方,如果黑客截取了 Web 浏览器和网站服务器之间的传输信息,就可以直接读懂其中的信息,因此 HTTP 协议不适合传输一些重要的、敏感的信息,例如信用卡密码及支付验证码等。

HTTPS 协议就是为了解决 HTTP 协议的这一安全缺陷而出生的,为了数据传输的安全,HTTPS 在 HTTP 的基础上加入了SSL 协议,SSL 依靠证书来验证服务器的身份,为浏览器和服务器之间的通信加密,这样即使黑客截取了发送过程中的信息,也无法破解读懂它,所以,网站及用户的信息便得到了最大的安全保障。

总体来说,HTTP 是超文本传输协议,信息是明文传输,HTTPS 则是具有安全性的 SSL 加密传输协议。HTTP 和 HTTPS 使用的是完全不同的连接方式,使用的端口也不一样,HTTP 默认是 80 端口,而 HTTPS 默认是 443 端口。

7. Cookie 和 Session 有什么区别?

Cookie 和 Session 之间有如下几点区别:

(1) Session 数据存放在服务端,Cookie 数据存放在客户端 (浏览器)。
(2) Session 的运行依赖 Session ID,而 Session ID 是存放在 Cookie 中的,即如果浏览器禁用了 Cookie,那么同时 Session 也会失效。在存储 Session 时,键与 Cookie 中的 Session ID 相同,值是开发人员设置的键值对信息,进行了 Base64 编码,过期时间由开发人员设置。
(3) Cookie 安全性比 Session 差。
(4) 单个 Cookie 保存的数据不能超过4k,很多浏览器都限制一个站点最多保存 20 个 Cookie。

8. 域名和 IP 之间有什么关系?如何查看某个域名对应的 IP 地址?

互联网 (Internet) 上有成千上百万台主机 (host),为了区分这些主机,人们给每台主机都分配了一个专门的 地址 作为标识,称为 IP 地址。由于 IP 地址全是数字,为了方便用户记忆,Internet 上引进了域名服务系统 DNS (Domain Name System)。当用户键入某个域名的时候,这个信息首先到达提供此域名解析的服务器上,域名解析器会将此域名解析为相应网站的 IP 地址。完成这一任务的过程就称为域名解析。

可以使用 ping、nslookup 等工具来查看某个域名对应的 IP 地址。如下图所示:

在这里插入图片描述

9. 在 HTTP 协议头中,keep-alive 字段有什么作用?

HTTP 协议采用 请求-应答 模式,当使用普通模式,即非 keep-alive 模式时,每个请求应答客户和服务器都要新建一个连接,完成之后立即断开连接 (HTTP 协议为无连接的协议)。

当使用 keep-alive 模式 (又称持久连接、连接重用) 时,keep-alive 功能使客户端到服务器端的连接持续有效。当出现对服务器的后续请求时,keep-alive 功能避免了建立或者重新建立连接。

通过使用 keep-alive 机制,可以减少 TCP 连接建立次数,也意味着可以减少 time_wait 状态连接,因此提高性能和提高 httpd 服务器的吞吐率。更少的 TCP 连接意味着更少的系统内核调用,socket 的 accept() 和 close() 调用。

10. HTTP 常用的状态码 (Status Code) 有哪些?

当用户访问一个网页时,浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含 HTTP 状态码的信息头 (server header) 用以响应浏览器的请求。HTTP 状态码的英文为 HTTP Status Code。HTTP 状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,HTTP 状态码共分为 5 种类型:

在这里插入图片描述
常见的 HTTP 状态码列表:

在这里插入图片描述
在这里插入图片描述

11. 常用的爬虫框架或者模块有哪些? 谈谈它们的区别或者优缺点?

Python 自带 urllib 和 urllib3,也可以使用第三方的 requests 库,或者 Scrapy 框架。

在 Python 2中,有 Urllib 和 Urllib2 两种模块,都是用来实现网络请求的发送功能。其中 Urllib2 可以接收一个 Request 对象,并通过这样的方式来设置一个 URL 的 Headers,而 Urllib 则只接收一个 URL,不能伪装用户代理等字符串操作。而在 Python3 中将 Urllib 与 Urllib2 模块的功能组合,并且命名为 urllib。Python3 中的 Urllib 模块中包含多个功能的子模块,具体内容如下:

(1) urllib.request:用于实现基本 HTTP 请求的模块。
(2) urllib.error:异常处理模块,如果在发送网络请求时出现了错误,可以捕获异常进行异常的有效处理。
(3) urllib.parse:用于解析 URL 的模块。
(4) urllib.robotparser:用于解析 robots.txt 文件,判断网站是否可以爬取信息。

urllib3 是一个功能强大,条理清晰,用于 HTTP 客户端的第三方模块,许多 Python 的原生系统已经开始使用 urllib3。urllib3 提供了很多 Python 标准库里所没有的重要特性:

(1) 线程安全。
(2) 连接池。
(3) 客户端 SSL/TLS 验证。
(4) 使用 multipart 编码上传文件。
(5) Helpers 用于重试请求并处理 HTTP 重定向。
(6) 支持 gzip 和 deflate 编码。
(7) 支持 HTTP 和 SOCKS 代理。
(8) 100% 的测试覆盖率。

由于 urllib3 模块为第三方模块,需要单独使用 pip 命令进行模块的安装。安装命令如下:

pip install urllib3

requests 是 Python 中实现 HTTP 请求的一种方式,requests 是第三方模块,该模块在实现 HTTP 请求时要比 urllib、urllib3 模块简化很多,操作更加人性化。requests 特性如下:

(1) Keep-Alive & 连接池 Unicode 响应体 自动解压
(2) 国际化域名和 URL、HTTP(S) 代理支持、支持 .netrc
(3) 带持久 Cookie 的会话、文件分块上传、分块请求
(4) 浏览器的 SSL 认证、流下载、优雅的 key/value Cookie
(5) 自动内容解码、连接超时、基本/摘要式的身份认证

Scrapy 是一个可以爬取网站数据,为了提供结构性数据而编写的开源框架。Scrapy 的用途非常广泛,不仅可以应用到网络爬虫中,还可以用于数据挖掘、数据监测以及自动化测试等。Scrapy 是基于 Twisted 的异步处理框架,架构清晰、可扩展性强,可以灵活地完成各种需求。Scrapy 框架的整体架构如图所示:

在这里插入图片描述

12. 真题

12.1 Robots 协议是什么?

答案:Robots 协议(也称为爬虫协议、爬虫规则、机器人协议等)的全称是 网络爬虫排除标准(Robots Exclusion Protocol),网站通过 Robots 协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取。Robots 协议是网站国际互联网界通行的道德规范,其目的是保护网站数据和敏感信息,以确保用户个人信息和隐私不被侵犯。因为它不是命令,所以需要搜索引擎自觉遵守。

12.2 爬虫能爬取哪些数据?

答案:只要能请求到的连接,基本上都可以获取。可以使网页文本:例如:HTML 文档,JSON 格式化文本等。可以是图片,获取到的是二进制文件,保存为图片格式。可以是视频,同样是二进制文件。

12.3 如何解析爬取到的数据?

答案:常用方法有:(1) 直接处理 (2) JSON 解析 (3) 正则表达式处理 (4) Beautifu Soup4 解析处理 (5) PyQuery 解析处理 (6) Xpath 解析处理。

12.4 列举使用过的 Python 网络爬虫所用到的网络数据包。

答案:urllib、urllib3、requests。

12.5 列举使用过的 Python 网络爬虫所用到的解析数据包。

答案:json、pyquery、lxml、bs4、re

12.6 通过爬虫爬取到的数据有哪些保存方式?

答案:可以通过以下几种方式来保存:(1) 文本:纯文本、Json 及 XML 等。(2) 关系型数据库:例如 MySQL、Oracle 及 SQL Server 等结构化数据库。(3) 非关系型数据库:MongoDB、Redis 等 key-value 形式存储。

12.7 常见的反爬虫机制有哪些?

答案:可以通过以下几种方案来解决:

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

(2) 基于用户行为反爬虫:动态变化IP 或通过间隔登录来爬取数据,模拟普通用户的行为。

有一部分网站是通过检测用户行为来进行反爬虫的,例如同一 IP 短时间内多次访问同一页面,或着同一账户短时间内多次进行相同操作。大多数网站都是前一种情况,对于这种情况,使用 IP 代理就可以解决。可以专门写一个爬虫,爬取网上公开的代理 IP,检测后全部保存起来。这样的代理 IP 爬虫经常会用到,最好自己准备一个。有了大量代理 IP 后可以每请求几次更换一个IP,这在 requests 或者 urllib 等网络库中很容易做到,这样就能很容易的绕过第一种反爬虫。对于第二种情况,可以在每次请求后随机间隔几秒再进行下一次请求。有些有逻辑漏洞的网站,可以通过请求几次、退出登录、重新登录、继续请求来绕过同一账号短时间内不能多次进行相同请求的限制。

(3) 基于动态页面的反爬虫:跟踪服务器发送的 Ajax 请求,模拟 Ajax 请求。

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

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

用这套框架几乎能绕过大多数的反爬虫,因为它不是在伪装成浏览器来获取数据 (上述的通过添加 Headers 一定程度上就是为了伪装成浏览器),它本身就是浏览器,phantomJS 就是一个没有界面的浏览器,只是操控这个浏览器的不是人。

12.8 如何提高爬取效率?

答案:可以从以下几个方面考虑:

(1) 爬取方面,利用异步 I/O。
(2) 处理方面,利用消息队列做生产者消费者模型。

12.9 简述 Beautiful Soup 模块的作用及基本使用?

答案:Beautiful Soup 是一个用于从 HTML 和 XML 文件中提取数据的 Python 模块。Beautiful Soup 提供一些简单的函数用来处理导航、搜索、修改分析树等功能。Beautiful Soup 模块中的查找提取功能非常强大,而且非常便捷,通常可以节省程序员数小时或数天的工作时间。

Beautiful Soup 自动将输入文档转换为 Unicode 编码,输出文档转换为 UTF-8 编码。开发者不需要考虑编码方式,除非文档没有指定一个编码方式,这时,Beautiful Soup 就不能自动识别编码方式了。此时,开发者仅仅需要说明一下原始编码方式就可以了。关于它的使用可以看博主 Python爬虫数据抽取(二):解析库Beautiful Soup 4 一文。

12.10 有一个 html 文本字符串,取出这个 a 标签里面的 href 的链接地址?

from bs4 import BeautifulSoup

str1 = "<a href='www.baidu.com'>amoxiang</a>"
html = BeautifulSoup(str1, "lxml")
print(html.find("a").attrs["href"])

12.11 简述同源策略

答案:同源策略需要同时满足三点要求:

① 协议相同
② 域名相同
③ 端口相同。

例如:http://www.test.com 与 https://www.test.com 不同源,因为它们的协议不同。
http://www.test.com 与 http://www.admin.com 不同源,因为它们的域名不同。
http://www.test.com 与 http://www.test.com:8081 不同源,因为它们端口不同。只要不满足其中任意一个要求,就不符合同源策略,就会出现 跨域

12.12 简述 Requests 模块的作用及基本使用?

答案:requests 是 Python 中实现 HTTP 请求的一种方式,requests 是第三方模块,该模块在实现 HTTP 请求时要比 urllib、urllib3 模块简化很多,操作更加人性化。基本使用:

发送 get 请求:requests.get()。
发送 post 请求:requests.post()。
读取请求返回内容:response.text。
二进制数据:response.content。
对响应结果进行 UTF-8 编码: response.encoding = “utf-8”
会话请求:requests.session()。
保存 Cookie:requests.cookies.RequestsCookieJar()。

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

答案:多进程爬虫可以认为是分布式爬虫的基础,在单机上也可以用。因为一般大型的网站的服务器都是采用分布式部署的,可以采用多进程同时在不同服务器上进行爬取。多线程爬虫优势:
(1) 有效利用 CPU 时间。
(2) 极大减小下载出错、阻塞对抓取速度的影响,整体上提高下载的速度。
(3) 对于没有反爬虫限制的网站,下载速度可以多倍增加。

局限性:

(1) 对于有反爬的网站,速度提升有限。
(2) 提高了复杂度,对编码要求更高。
(3) 线程越多,每个线程获得的时间就越少,同时线程切换更频繁也带来额外开销。
(4) 线程之间资源竞争更激烈。

在实际的数据采集过程中,既考虑网速和响应的问题,也需要考虑自身机器的硬件情况,来设置多进程或多线程。因此,如果需要爬取的数据任务量大,那么可以考虑多进程+多线程的机制。先创建多个进程完成不同的任务,然后每个进程内部再创建多个线程,最后完成需要爬取到的数据。

12.14 在不使用动态爬取的情况下,如何解决同时限制 IP、Cookie、Session (其中有一些是动态生成的) ?

答案:解决限制 IP 可以使代理 IP 地址池、服务器;不适用动态爬取的情况下可以使用反编译 JS 文件获取相应的文件,或者换用其他平台 (例如手机端) 可以获取相应的 JSON 文件。

12.15 在爬虫的过程中,如何解决验证码的问题?

答案:图形验证码:干扰、杂色不是特别多的图片可以使用开源库 Tesseract 进行识别,太过复杂验证码则需要借助第三方打码平台来处理。点击和拖动滑块验证码可以借助 Selenium、无图形界面浏览器 (chromedriver 或者 phantomjs) 和 pillow 包来模拟人的点击和滑动操作来解决,pillow 可以根据色差识别需要滑动的位置。

12.16 Cookie 过期如何处理?

答案:因为 Cookie 存在过期的现象,一个很好的处理方法就是自定义一个异常类,如果有异常的话,那么 Cookie 抛出异常类在执行程序。

12.17 HTTPS 有什么优点和缺点?

答案:优点包括以下内容:

(1) 使用 HTTPS 协议可认证用户和服务器,确保数据发送到正确的客户机和服务器。
(2) HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,要比 HTTP 协议安全,可防止数据在传输过程中被窃取、改变,从而确保数据的完整性。
(3) HTTPS 是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成本。

缺点包括以下内容:

(1) HTTPS 协议的加密范围也比较有限,在黑客攻击、拒绝服务攻击及服务器劫持等方面几乎起不到什么作用。
(2) HTTPS 协议还会影响缓存,增加数据开销和功耗,甚至已有安全措施也会受到影响。
(3) SSL 证书需要钱。功能越强大的证书费用越高。个人网站、小网站没有必要,一般不会用。
(4) HTTPS 连接服务器端资源占用高很多,握手阶段比较费时,对网站的响应速度有负面影响。
(5) HTTPS 连接缓存不如 HTTP 高效。

12.18 HTTPS是如何实现数据的安全传输的?

答案:HTTPS 其实就是在 HTTP 跟 TCP 中间多加了一层加密层 TLS/SSL。SSL 是个加密套件,负责对 HTTP 的数据进行加密。TLS 是 SSL 的升级版。现在提到 HTTPS,加密套件基本指的是 TLS。原先是应用层将数据直接给到 TCP 进行传输,现在改成应用层将数据给到 TLS/SSL,将数据加密后,再给到 TCP 进行传输。

12.19 代理 IP 里的 透明、匿名、高匿 分别指的是什么?

答案:透明代理的意思是客户端根本不需要知道有代理服务器的存在,但是它传送的仍然是真实的IP。普通匿名代理能隐藏客户机的真实IP,但会改变用户的请求信息,服务器端有可能会认为使用了代理。不过使用此种代理时,虽然被访问的网站不能知道请求者的 IP 地址,但任然可以知道请求者在使用代理,当然某些能够侦测 IP 的网页仍然可以查到请求者的 IP。

高匿名代理不改变客户机的请求,这样在服务器看来就像有个真正的客户浏览器在访问它,这时客户的真实 IP 是被隐藏的,服务器端不会认为请求者使用了代理。设置代理有以下两个好处:

(1) 让服务器以为不是同一个客户端在请求。
(2) 防止真实地址被泄露,防止被追究。

12.20 什么是 Xpath?

答案:XPath 的英文全称是 XML Path Language,中文是XML 路径语言,它是一种在 XML 文档中查找信息的语言,最初是用于在 XML 文档中搜索节点的,但同样可用于 HTML 文档的搜索,因为 XML 与 HTML 是同源的。XPath 的功能非常强大,它提供了非常简单的路径选择表达式。另外,它还提供了超过 100 个内建函数,用于字符串、数值、时间的匹配以及节点、序列的处理等。几乎所有想定位的节点,都可以用XPath来选择。Xpath 的基本语法规则:

在这里插入图片描述

12.21 lxml 库的作用有哪些?

答案:lxml 是 Python 的一个解析库,用于解析 HTML 和 XML,支持 Xpath 解析方式。由于 lxml 底层使用 C 语言编写的,所以解析效率非常高,同时 lxml 也继承了 libxml2 的特性自动修正 HTML 代码,利用 pip 安装即可。

pip install lxml

猜你喜欢

转载自blog.csdn.net/xw1680/article/details/109735511
今日推荐