爬虫
1. 请阐述通用爬虫和聚焦爬虫的概念
通常情况下,我们将搜索引擎使用的爬虫我们称之为通用爬虫,就像谷歌
和百度的爬虫,它的作用是把整个互联网上的网页下载到本地,形成一个互联
网内容的镜像备份,在对这些网页进行一定的处理(例如提取关键字、去掉广
告等)之后,就可以提供一个用户检索内容的接口。一般的网站都会通过
robots 协议来告诉通用爬虫,哪些那些页面可以抓取,那些不可以抓取。
我们做 Python 爬虫开发通常是开发聚焦爬虫,聚焦爬虫会针对某种特定
的内容进行爬取,因此会对爬取的内容进行筛选和处理,而且只是抓取与特
定主题需求有相关性的内容。
2. 完整的一个 url 都包含哪些内容
一个完整的 url 包含协议、主机地址、端口、路径和资源。其中不同的协
议代表不同的资源查找方式、资源传输方式;主机地址指的是存放资源的主
机(服务器)的 IP 地址(域名),端口是用来区分不同的服务的,路径是指资
源在主机中的具体位置。
3. 请阐述 http 协议和 https 协议的区别和联系
HTTPS 协议需要到证书颁发机构(CA)申请证书,一般免费证书很少,
需要向证书颁发机构支付费用。 HTTP 协议是超文本传输协议,信息是明文传
输,HTTPS 则是具有安全性的 SSL 加密传输协议。采用 HTTP 协议传输数据
的客户端和服务器,客服端给服务器发送请求,服务器接收到请求会直接将
数据返回。采用 HTTPS 协议的时候,客服端给服务器发送请求,服务器接收
到请求后不会马上将数据返回,而是将一个证书传递给客服端(这个证书中
包含了公钥),客户端信任这个证书后,客户端发出的信息会经过加密然后再
发送给服务器。服务器接收到信息后会使用服务器的私钥进行解密。同样
的,服务器发送给客户端的信息也会通过私钥进行加密,在客户端通过公钥
进行解密。
4. robots 协议是什么
Robots 协议,有时候也称为“爬虫协议” 或“网络机器人协议” ,它的
全称是“网络爬虫排除标准” (Robots Exclusion Protocol),网站通过
Robots 协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取。 Robots
协议对应的文本 robots.txt 通常保存在网站的根目录下,是一个使用 ASCII 码
字符的纯文本文件,例如我们访问HTTP://www.taobao.com/robots.txt就可以查看到淘宝的 robots 协议文件。 Robots 协议并不是一个强制执行的
法律法规,而是约定俗成的道德规范,所以它并不能保证网站的隐私。
目前爬虫领域仍属于拓荒阶段,因为爬取的数据就是浏览器中能够让用户
看到的东西,所以“法不禁止即为许可” 。但是在使用其他网站提供的数据
时,必须要尊重网站的知识产权,即便是网站上的数据都由使用网站的用户
提供的,但是网站平台是投入了运营成本的,当用户在注册和发布内容时,
平台通常就已经获得了对数据的所有权、使用权和分发权。如果侵犯知识产
权或者有损害动产的行为,在打官司时败诉的可能性是相当高的。
5. 请说出 http 请求包含哪几部分,至少 4 个常见的请求头以及含义
HTTP 请求包含请求头和请求体两个部分。请求头包含对客户端的环境描
述和客户端请求信息等。请求体就是客户端要发送给服务器的数据。
比如登录注册的时候,客服端需要将账号密码发送给服务器,那么这个时候的账号
密码数据就可以作为请求体发送给服务器。
常见的请求头:
Host: 客户端想访问的服务器主机地址
User-Agent: 客户端的类型,客户端的软件环境
Accept: 客户端所能接收的数据类型
Accept-Language: 客户端的语言环境
Accept-Encoding: 客户端支持的数据压缩格式
6.请说出 http 响应包含哪几部分,至少 4 个常见状态码以及含义
HTTP 响应包含响应头和响应体。响应头包含了对服务器的描述和对返回
数据的描述,响应体就是服务器要给客户端返回的数据。
200:请求被成功接收
304:再次请求时,请求的内容没有发生改变
403:客户端错误,没有权限,拒绝访问
404:服务器无法根据客户端请求找到资源
500:服务器内部错误,无法完成请求
7.用过的爬虫模块和爬虫框架都有哪些,简述优缺点
- 下载数据 - urllib / requests / aioHTTP。
- 解析数据 - re / lxml / beautifulsoup4(bs4)/ pyquery。
- 缓存和持久化 - pymysql / sqlalchemy / peewee/ redis /
pymongo。 - 生成数字签名 - hashlib。5. 序列化 - pickle / json。
- 压缩 - zlib。
- 调度器 - 进程(multiprocessing) / 线程(threading) / 协程
(coroutine)。 - 框架 - Scrapy 和 PySpider。
8.讲述模拟登陆流程和爬虫中如何使用 cookie
模拟登陆可以分为两种方式,第一种使用自动化测试框架 Selenium,
Selenium 调用 Chrome 浏览器来模拟人的行为,通过 Chrome 浏览器打开
登陆页面,并通过获取输入账号密码的输入框,并自动的填入账号密码内
容,并模拟点击登陆,即可实现登录操作。第二种使用模拟 Ajax 请求,分析
页面中登录的 URL 地址,传递参数,使用这种方式模拟 API 接口进行登录。
9.图片防盗链技术是如何实现的以及如何实现下载防盗链图片
网站防图片盗链接通常是检查获取图片的 HTTP 请求头中的 Referer 字
段,该字段的作用是告诉服务器获取图片的请求是从哪个页面链接过来的,
如果没有该字段或者该字段中的页面并不是本网站,那就可以认定为盗链接
行为,从而通过拦截过滤器(在 Django 中是中间件)加以拒绝。知道了这
一点也破解防盗链接也非常简单,就是在 HTTP 请求的请求头中添加 Referer
字段,并指定为提供图片的网站的某个有效的 URL 即可。
10.常见的 html 文件解析方式都有哪些
正则表达式解析, 速度快, 如: re
XPath 解析, 速度快, 如:lxml
CSS 选择器解析, 速度慢, 如: bs4 , pyquery
11.什么是懒加载技术,如何爬取懒加载的图片
在很多网站中,如果页面中的图片内容非常多,那当用户在访问该页面
时,页面中的图片不用全部都加载出来,只用加载在浏览器框中的展示的部
分图片即可,因此懒加载就是当用户浏览到该图片信息时,才加载 img 中的
src 属性。实现懒加载关键点如下:1 页面中的 img 元素,如果没有 src 属性,
浏览器就不会发出请求去下载图片(也就没有请求,也就提高性能),一旦通
过 javascript 设置了图片路径,浏览器才会送请求。 2 如何获取真正的路径,
真正的路径存在元素的“data-url” 属性里,当浏览器在访问到该图片时,将
data-url 地址设置到 src 属性中即可。
12.如果爬取的数据为 json 数据,如何解析
通过 Python 内置的 json 模块中的 loads 函数可以将 JSON 格式的数据解析
成 Python 的字典或数组。
13.selenium+phantomjs 是什么,有什么作用
首先 Selenium 是一个自动化测试工具,利用它可以驱动浏览器执行特定
的动作,如点击、表单操作等,同时还可以获取浏览器上呈现的页面源代码,
做到可见即可爬。
对于一些 Javascript 动态渲染的页面来说,此种抓取方式非常有效。
PhantomJS 是一个无头浏览器(headless browser),也称无界面浏览器,
它是一个支持脚本编程的 Webkit 浏览器引擎。由于 PhantomJS 是无界面浏
览器,爬取时不需要开界面,占用的内存较小,所以运行起来比打开界面的
爬取方式更高效。除了 PhantomJS 支持无头浏览器模式,目前主流的浏览器
如 Chrome 和 Firefox 也已支持 headless 浏览器模式进行无界面爬取。
14.阐述 scrapy 基本结构和工作原理
Scrapy 是一个为了爬取网站数据、提取结构性数据而编写的应用框架。
Scrapy Engine(Scrapy 引擎):Scrapy Engine 是用来控制整个爬虫系
统的数据处理流。
Scheduler(调度器):Scheduler 维护着待爬取的 URL 队列,当调度程
序从 Scrapy Engine 接受到请求时,会从待爬取的 URL 队列中取出下一个
URL 返还给他们。
Downloader(下载器):Downloader 从 Scrapy Engine 那里得到需要
下载的 URL,并向该网址发送网络请求进行页面网页,最后再将网页内容传递
到 Spiders 来处理。如果需要定制更复杂的网络请求,可以通过 Downloader
中间件来实现,
Spiders(蜘蛛):Spiders 是用户需要编辑的代码的部分。用户通过编写
spider.py 这个类实现指定要爬取的网站地址、定义网址过滤规则、解析目标
数据等。 Spider 发出请求,并处理 Scrapy Engine 返回给它下载器响应数
据,把解析到的数据以 item 的形式传递给 Item Pipeline,把解析到的链接传
递给 Scheduler。
Item Pipeline(项目管道):Item 定义了爬虫要抓取的数据的字段,类
似于关系型数据库中表的字段名,用户编写 item.py 文件来实现这一功能。
Pipeline 主要负责处理 Spider 从网页中抽取的 item,对 item 进行清洗、验
证,并且将数据持久化,如将数据存入数据库或者文件。用户编写pipeline.py 实现这一功能。
Downloader middlewares(下载器中间件):Downloader
middlewares 是位于 Scrapy Engine 和 Downloader 之间的钩子框架,主要
是处理 Scrapy Engine 与 Downloader 之间的请求及响应。可以代替接收请
求、处理数据的下载以及将结果响应给 Scrapy Engine。
Spider middlewares(蜘蛛中间件):Spider middlewares 是介于
Scrapy Engine 和 Spiders 之间的钩子框架,主要是处理 Spiders 的响应输
入和请求输出。可以插入自定义的代码来处理发送给 Spiders 的请求和返回
Spider 获取的响应内容和项目。
15.怎么理解进程和线程
进程是指在系统中 正在运行的一个应用程序。 进程之间是独立的,每个
进程均运行在其专用且受保护的内存空间内。所有的应用程序都是通过代码
来实现的(不管是什么语言),所以应用程序就可以看成是我们写好的一个代
码,进程就是我们正在执行这个代码。代码中我们避免不了要声明很多的变
量去保存各种各样的数据,那么这些数据就是保存在这个进程对应的内存空
间中的。当进程对应的代码执行结束了,进程就结束,其对应的内存空间也
会被释放。进程要想执行任务,必须得有线程(每个进程至少要有一条线
程)。 一个进程(程序)的所有任务都在线程中执行。如果把进程可以看成
是一个车间,线程就是车间里面的工人。车间的特点就是,每一个车间都有
一个属于自己专有的空间。并且一个车间里面可以有多个工人。但是车间想
要生产,那么车间中至少要一个工人。
16.如何理解同步、异步、并行、并发
同步: 多任务, 多个任务之间执行的时候要求有先后顺序,必须一个先
执行完成之后,另一个才能继续执行, 只有一个主线。
异步: 多任务, 多个任务之间执行没有先后顺序,可以同时运行,执行
的先后顺序不会有什么影响,存在的多条运行主线
并行和并发都可以看成是多个任务可以同时执行。但是他们之间有差别,并行
才是指真正的同时执行但是要真正做到并行需要多核的支撑,并发是通过时间
切片,让 cpu 快速在多个任务之间切换造成的同时执行的假象。
17.scrapy 和 scrapy-redis 有什么区别
Scrapy 是一个通用的爬虫框架,但是本身不支持分布式。 Scrapy-Redis
是为了更方便地实现 Scrapy 分布式爬取,提供了以 Redis 为基础的组件。
通过 Scrapy-Redis 组件可以提供的主要功能包括:- 爬取队列的功能
- 去重过滤的功能
- 和中断后重新爬取的功能
18.爬取过程中碰到验证码如何解决
关于这个问题,可以参考《你遇到过哪些反爬措施以及应对的手段是什么》这
个问题的答案。
19.阐述 crawlspider 的定义以及用法
CrawlSpider 是 Spider 的派生类,Spider 类的设计原则是只爬取
start_url 列表中的网页,而 CrawlSpider 类定义了一些规则来提供跟进网址
的方便的机制,从爬取的网页中获取网址并继续爬取的工作更适合。
CrawlSpider 的基本用法如下所示。
首先生成 scrawlspider 的命令为 :
[ scrapy genspider -t crawl 爬虫名 网站域名 ]
然后修改生成的 crawlspider 类,CrawlSpider 继承于蜘蛛类,除了继承
过来的属性外,还提供了新的属性和方法,如:LinkExtractors 功能为提取链
接,LinkExtractors 要实例化一次,并且它的 extract_links 方法会根据不同
的响应多次调用提取链接;rule 属性,在规则中包含一个或多个规则对象。
每个规则对爬取网站的动作定义了特定操作,如果多个规则匹配了相同的链
接,则根据规则在本集合中被定义的顺序,第一个会被使用。在 rule 里需要
定义 callback 方法,但由于 CrawlSpider 使用 parse 方法来实现其内部逻
辑, callback 方法不能命名为 parse。
20.阐述代理是什么以及你如何使用代理
当我们需要大量的爬取网站信息时,除了切换 User-Agent 之外,另外一
个重要的方式就是设置 IP 代理,以防止我们的爬虫被拒绝。设置 IP 代理通常
情况下可以使用第三方的接口,也可以自己做 IP 代理池。通常情况下,一些
代理网站会提供一些免费的 ip 代理,但是其稳定性和可用性很难得到保证。
另外一个代理就是设置 User-Agent,用以模拟不同的浏览器的访问行为。
21.scrapy 在爬取过程中出现断网如何保证数据完整
任何程序在运行的过程中都有可能会崩溃,爬虫也不例外。当我们需要爬
取的数据量很大很大的时候,爬取的过程中难免会出现各种各样的问题导致程
序崩溃断掉,这个时候我们就需要记录爬虫的状态,当爬虫挂掉的时候可以恢
复原来的状态继续跑。 Scrapy 简单易用,效率极高,自带多线程机制。但是也
正因为它的多线程机制导致在用 Scrapy 写爬虫的时候处理断点续爬很恼火。当请求中加入了优先级属性的时候,每次 Scrapy 从请求队列中取请求的时候
就会判断优先级,先取出优先级高的去访问。由于 Scrapy 默认启动十个线程。
这时优先级为 100 的就会在优先级为 90 之前被取出请求队列,这样呢我们就
能大体上保证爬取网页的顺序性。保证了顺序性之后呢,我们就要记录已经爬
取的页数。由于发送请求、下载页面、存取数据这几个动作是顺序执行的,也
就是说程序发送了这个请求不代表此时已经爬取到这一页了,只有当收到响应
的时候我们才能确定我们已经获取到了数据,这时我们才能记录爬取位置。
22.要爬取的内容为动态加载,如何实现爬取
为了加速页面的加载速度,页面的很多部分都是用 JavaScript 生成的,
而对于用 scrapy 爬虫来说就是一个很大的问题,因为 Scrapy 本身并没有
JavaScript 引擎,所以爬取的都是静态页面。如何分析网站上动态加载出来
的内容,可以通过查看管理员工具获得网站发送的 Ajax 请求,通过调用 Ajax
请求拿到返回的 JSON 数据,返回的 JSON 数据就是网页中动态渲染的数
据。另外一种方式是使用自动化测试工具 Selenium 加载 PhantomJS 或
ChromeDriver 等浏览器来加载动态内容。
23.请阐述分布式爬虫实现的原理
分布式爬虫实际上就是在多台主机上同时运行爬虫任务协同爬取,协同爬
取的前提是共享同一个爬取请求队列,各台主机不需要维护自己的爬取请求队
列,而是从共享队列存取请求。但每台主机有各自的调度器和下载器,所以调
度和下载功能分别完成,这样就可以多台主机协同爬取,爬取效率成倍提高。
我们可以通过使用 Redis 的数据结构(如列表,集合,有序集合)来实现
共享爬取请求队列
通过利用 Redis 的集合来实现分布式请求的去重
通过调度器对 Redis 的爬取请求队列进行判断,当 Redis 队列为空时,爬虫重
新爬取,如果不为空,爬虫接着上次中断处继续爬取。
24.你都遇到过哪些反爬措施以及解决方式
- 检查 HTTP 请求头。
Accept
User-Agent - 三方库 fake-useragent
Referer
Accept-Encoding
Accept-Language2. 检查网站的 Cookie。
-
有用的插件:EditThisCookie
2.如何处理脚本动态生成的 Cookie
构建 Cookie 池
- 动态生成页面内容。
- JavaScript 逆向。
- Selenium + PhantomJS。
- 对访问频率进行限制。
- 对爬虫进行限速。
- 隐藏身份
- IP 代理 - 快代理 / 讯代理 / 芝麻代理 / 蘑菇代理。
- TOR - 洋葱路由,基本不考虑。
- 填写表单或输入验证码。
- 用 RoboBrowser 这样的工具辅助提交表单。
- OCR(Tesseract)+ 机器学习训练,商业项目一般不考虑 。
- 专业识别平台 - 超级鹰 / 云打码。
- 爬虫陷阱(蜜罐)。
- 网页上有诱使爬虫爬取的爬取的隐藏链接(陷阱或蜜罐),可以通过自
动化测试工具 Selenium 调用 PhantomJS 或 ChromeDriver 来判断链接是否可
见或者是否出现在可视区域来避开。
25.使用过 Scrapy 中间件吗, 使用场景有哪些
Scrapy 中有以下几个中间件,分别为蜘蛛中间件(spider
middleware)和下载器中间件(downloader middleware)。蜘蛛中间件是
在运行过程中进行一些处理,而下载器中间件是在页面被下载时进行的一些处
理。
蜘蛛中间件有以下几个函数被管理:process_spider_input 接收一个
response 对象并处理,process_spider_exception 在爬虫出现的异常时被
调用,process_spider_output 当 Spider 处理 response 返回 result 时,该
方法被调用,process_start_requests 当 spider 发出请求时被调用。
下载中间件有以下几个函数被管理:proc ess_request 在请求通过下载中
间件时被调用,process_response 在下载结果经过中间件时被调用,
process_exception 在下载出现异常时被调用
Scrapy框架使用过程:
1.首先Spiders(爬虫)将需要发送请求的url(requests)经ScrapyEngine(引擎)交给Scheduler(调度器)。
2.Scheduler(排序,入队)处理后,经ScrapyEngine,DownloaderMiddlewares(可选,主要有User_Agent, Proxy代理)交给Downloader。
3.Downloader向互联网发送请求,并接收下载响应(response)。将响应(response)经ScrapyEngine,SpiderMiddlewares(可选)交给Spiders。
4.Spiders处理response,提取数据并将数据经ScrapyEngine交给ItemPipeline保存(可以是本地,可以是数据库)。
提取url重新经ScrapyEngine交给Scheduler进行下一个循环。直到无Url请求程序停止结束。