7 爬虫基础
7.1 HTTP基本原理
7.1.1 URI 和 URL
URI 的全称为 Uniform Resource Identifier,即统一资源标志符,URL 的全称为 Universal Resource Locator,即统一资源定位符。
举例来说,https://github.com/favicon.ico,它是一个 URL,也是一个 URI。即有这样的一个图标资源,我们用 URL/URI 来唯一指定了它的访问方式
这其中包括了
- 访问协议https
- 访问路径(即根目录)
- 资源名称 favicon.ico
通过这样一个链接,我们便可以从互联网上找到这个资源,这就是 URL/URI。
URL 是 URI 的子集,也就是说每个 URL 都是 URI,但不是每个 URI 都是 URL。那么,怎样的 URI 不是 URL 呢?URI 还包括一个子类叫作 URN,它的全称为 Universal Resource Name,即统一资源名称。URN 只命名资源而不指定如何定位资源,比如 urn:isbn:0451450523 指定了一本书的 ISBN,可以唯一标识这本书,但是没有指定到哪里定位这本书,这就是 URN。
URI格式:
scheme://[username:password@]hostname[:port][/path][;parameters][?query][#fragment]
scheme
:协议。比如常用的协议有 http、https、ftp 等等,另外 scheme 也被常称作 protocol,都代表协议的意思。username
:password
:用户名和密码。在某些情况下 URL 需要提供用户名和密码才能访问,这时候可以把用户名密码放在 host 前面。比如 https://ssr3.scrape.center 这个 URL 需要用户名密码才能访问,那么可以直接写为 https://admin:admin@ssr3.scrape.center 则可以直接访问。hostname
:主机地址。可以是域名或 IP 地址,比如 https://www.baidu.com 这个 URL 中的 hostname 就是 www.baidu.com,这就是百度的二级域名。比如https://8.8.8.8
这个 URL 中 hostname 就是 8.8.8.8,它是一个 IP 地址。port
:端口。这是服务器设定的服务端口,比如https://8.8.8.8:12345
这个 URL 中的端口就是 12345。但是有些 URL 中没有端口信息,这是使用了默认的端口,http 协议的默认端口是 80,https 协议的默认端口是 443。所以 <https://www.baidu.com 其实相当于 https://www.baidu.com:443,而 http://www.baidu.com 其实相当于 http://www.baidu.com:80。path
:路径。指的是网络资源在服务器中的指定地址,比如 https://github.com/favicon.ico 这里 path 就是 favicon.ico,指的就是访问 GitHub 上的根目录下的 favicon.ico 这个资源。parameters
:参数。用来制定访问某个资源的时候的附加信息,比如 https://8.8.8.8:12345/hello;user 这里的 user 就是 parameters。但是 parameters 现在用得很少,所以目前很多人会把该参数后面的 query 部分称为参数,甚至把 parameters 和 query 混用。严格意义上来说,parameters 是分号;后面的内容。query
:查询。用来查询某类资源,如果有多个查询,则用 & 隔开。query 其实非常常见,比如 https://www.baidu.com/s?wd=nba&ie=utf-8,这里的 query 部分就是 wd=nba&ie=utf-8,这里指定了 wd 是 nba,ie 是 utf-8。由于 query 比刚才所说的 parameters 使用频率高太多,所以平时我们见到的参数、GET 请求参数、parameters、params 等称呼多数情况指代的也是 query。严格意义上来说,其实应该用 query 来表示。fragment
:片段。它是对资源描述的部分补充,可以理解为资源内部的书签。目前它有两个主要应用,一个是用作单页面路由,比如 现代前端框架 Vue、React 都可以借助它来做路由管理;另外一个应用是用作 HTML 锚点,用它可以控制一个页面打开时自动下滑滚动到某个特定的位置。
7.1.2 HTTP和HTTPS
URL支持的协议有很多,比如 http、https、ftp、sftp、smb 等等。
在爬虫中,我们抓取的页面通常基于 http 或 https 协议
HTTP 的全称是 Hyper Text Transfer Protocol,中文名叫作超文本传输协议。HTTP 协议是用于从网络传输超文本数据到本地浏览器的传送协议,它能保证高效而准确地传送超文本文档。
「超文本」 它就是超越了普通文本的文本,它是文字、图片、视频等的混合体,最关键有超链接,能从一个超文本跳转到另外一个超文本。
Chrome浏览器里面打开任意一个页面,右击任一地方并选择 “检查” 项(或者直接按快捷键 F12),即可打开浏览器的开发者工具,这时在 Elements 选项卡即可看到当前网页的源代码,这些源代码都是超文本.
HTTPS 的全称是 Hyper Text Transfer Protocol over Secure Socket Layer,是以安全为目标的 HTTP 通道,简单讲是 HTTP 的安全版,即在 HTTP 下加入 SSL 层,简称为 HTTPS
HTTPS 的安全基础是 SSL,因此通过它传输的内容都是经过 SSL 加密的,它的主要作用分为以下两种。
- 建立一个信息安全通道,保证数据传输的安全性
- 确认网站的真实性。凡是使用了 https 的网站,都可以通过点击浏览器地址栏的锁头标志来查看网站认证之后的真实信息,也可以通过 CA 机构颁发的安全签章来查询
7.1.3 HTTP请求过程
浏览器向网站所在的服务器发送了一个请求,网站服务器接收到这个请求后进行处理和解析,然后返回对应的响应,接着传回给浏览器。
Chrome浏览器里面, Network 面板, 然后刷新网页,这时候就可以看到在 Network 面板下方出现了很多个条目,其中一个条目就代表一次发送请求和接收响应的过程.
- 第一列 Name:请求的名称,一般会将 URL 的最后一部分内容当作名称。
- 第二列 Status:响应的状态码,这里显示为 200,代表响应是正常的。通过状态码,我们可以判断发送了请求之后是否得到了正常的响应。
- 第三列 Protocol:请求的协议类型,这里 http/1.1 代表是 HTTP 1.1 版本,h2 代表 HTTP 2.0 版本。
- 第四列 Type:请求的文档类型。
- 第五列 Initiator:请求源。用来标记请求是由哪个对象或进程发起的。
- 第六列 Size:从服务器下载的文件和请求的资源大小。如果是从缓存中取得的资源,则该列会显示 from cache。
- 第七列 Time:发起请求到获取响应所用的总时间。
- 第八列 Waterfall:网络请求的可视化瀑布流。
7.1.4 请求(Request)
Request,由客户端向服务器发出,可以分为 4 部分内容:
请求方法(Request Method)
GET
/POST
请求的网址(Request URL)
请求头(Request Headers)
Cookie
:也常用复数形式 Cookies,这是网站为了辨别用户进行会话跟踪而存储在用户本地的数据。它的主要功能是维持当前访问会话。例如,我们输入用户名和密码成功登录某个网站后,服务器会用会话保存登录状态信息,后面我们每次刷新或请求该站点的其他页面时,会发现都是登录状态,这就是 Cookie 的功劳。Cookie 里有信息标识了我们所对应的服务器的会话,每次浏览器在请求该站点的页面时,都会在请求头中加上 Cookie 并将其发送给服务器,服务器通过 Cookie 识别出是我们自己,并且查出当前状态是登录状态,所以返回结果就是登录之后才能看到的网页内容。Referer
:此内容用来标识这个请求是从哪个页面发过来的,服务器可以拿到这一信息并做相应的处理,如做来源统计、防盗链处理等。User-Agent
:简称 UA,它是一个特殊的字符串头,可以使服务器识别客户使用的操作系统及版本、浏览器及版本等信息。在做爬虫时加上此信息,可以伪装为浏览器;如果不加,很可能会被识别为爬虫。
请求体(Request Body)
- Request Body 一般承载的内容是
POST
请求中的表单数据,而对于GET请求,请求体则为空。
- Request Body 一般承载的内容是
GET 请求中的参数包含在 URL 里面,数据可以在 URL 中看到;而 POST 请求的 URL 不会包含这些数据,数据都是通过表单形式传输的,会包含在请求体中。URL 里。
例如, GET https://www.baidu.com/s?wd=Python
GET 请求提交的数据最多只有 1024 字节,而 POST 方式没有限制。
方法 | 描述 |
---|---|
GET | 请求页面,并返回页面内容 |
HEAD | 类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头 |
POST | 大多用于提交表单或上传文件,数据包含在请求体中 |
PUT | 从客户端向服务器传送的数据取代指定文档中的内容 |
DELETE | 请求服务器删除指定的页面 |
CONNECT | 把服务器当作跳板,让服务器代替客户端访问其他网页 |
OPTIONS | 允许客户端查看服务器的性能 |
TRACE | 回显服务器收到的请求,主要用于测试或诊断 |
7.1.5 响应(Response)
响应,即 Response,由服务器返回给客户端,可以分为三部分:
- 响应状态码(Response Status Code)
- 响应头(Response Headers)
- Date:标识响应产生的时间。
- Last-Modified:指定资源的最后修改时间。
- Content-Encoding:指定响应内容的编码。
- Server:包含服务器的信息,比如名称、版本号等。
- Content-Type:文档类型,指定返回的数据类型是什么,如 text/html 代表返回 HTML 文档,application/x-javascript 则代表返回 JavaScript 文件,image/jpeg 则代表返回图片。
- Set-Cookie:设置 Cookie。响应头中的 Set-Cookie 告诉浏览器需要将此内容放在 Cookie 中,下次请求携带 Cookie 请求。
- Expires:指定响应的过期时间,可以使代理服务器或浏览器将加载的内容更新到缓存中。
- 响应体(Response Body)
7.1.6 HTTP 2.0
HTTP/2.0 变得更快、更简单、更稳定,HTTP/2.0 在传输层做了很多优化,HTTP/2.0 的主要目标是通过支持完整的请求与响应复用来减少延迟,并通过有效压缩 HTTP 请求头字段将协议开销降至最低,同时增加对请求优先级和服务器推送的支持。
HTTP/2.0 所有性能增强的核心就在于这个新的二进制分帧层。在 HTTP/1.x 中,不管是请求(Request)还是响应(Response),它们都是用文本格式传输的,其头部(Headers)、实体(Body)之间也是用文本换行符分隔开的。HTTP/2.0 对其做了优化,将文本格式修改为了二进制格式,使得解析起来更加高效。同时将请求和响应数据分割为更小的帧,并采用二进制编码。
帧:只存在于 HTTP/2.0 中的概念,是数据通信的最小单位,比如一个请求被分为了请求头帧(Request Headers frame)和请求体 / 数据帧(Request Data frame)。 数据流:一个虚拟通道,可以承载双向的消息,每个流都有一个唯一的整数 ID 来标识。 消息:与逻辑请求或响应消息对应的完整的一系列帧。
- 帧:只存在于 HTTP/2.0 中的概念,是数据通信的最小单位,比如一个请求被分为了请求头帧(Request Headers frame)和请求体 / 数据帧(Request Data frame)。
- 数据流:一个虚拟通道,可以承载双向的消息,每个流都有一个唯一的整数 ID 来标识。
- 消息:与逻辑请求或响应消息对应的完整的一系列帧。
一些编程语言的库还没有完全支持 HTTP/2.0,比如对于 Python 来说,
hyper
、httpx
等库已经支持了 HTTP/2.0,但广泛使用的requests
库依然还是只支持 HTTP/1.1。
7.1.7 网络传输层级
7.2 Web网页基础
7.2.1 网页的组成
网页可以分为三大部分 —— HTML
、CSS
和 JavaScript
。
如果把网页比作一个人的话,HTML 相当于骨架,JavaScript 相当于肌肉,CSS相当于皮肤,三者结合起来才能形成一个完善的网页。
HTML
HTML其英文叫做 HyperText Markup Language 中文翻译叫做超文本标记语言,但我们通常不会用中文翻译来称呼它,一般就叫 HTML。HTML 是用来描述网页的一种语言,网页包括文字、按钮、图片和视频等各种复杂的元素。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>This is a Demo</title>
</head>
<body>
<div id="container">
<div class="wrapper">
<h2 class="title">Hello World</h2>
<p class="text">Hello, this is a paragraph.</p>
</div>
</div>
</body>
</html>
CSS
HTML 定义了网页的结构,但是只有 HTML 页面的布局并不美观,可能只是简单的节点元素的排列。为了让网页看起来更好看一些,这里借助了 CSS。
CSS,全称叫作Cascading Style Sheets,即层叠样式表。“层叠” 是指当在 HTML 中引用了数个样式文件,并且样式发生冲突时,浏览器能依据层叠顺序处理。“样式” 指网页中文字大小、颜色、元素间距、排列等格式。CSS 是目前唯一的网页页面排版样式标准,有了它的帮助,页面才会变得更为美观。
在上图中,Styles 面板呈现的就是一系列 CSS 样式,比如摘抄一段 CSS,内容如下:
>
<style
h2 {color: blue;
font-size: xx-large;
border-radius: 1cm;
background-color: aquamarine;
}> </style
这就是一个 CSS 样式。大括号前面是一个 CSS 选择器。
JavaScript
JavaScript,简称 JS,是一种脚本语言。HTML 和 CSS 配合使用,提供给用户的只是一种静态信息,缺乏交互性。
JavaScript 通常也是以单独的文件形式加载的,后缀为js,在 HTML 中通过 script
标签即可引入,例如:
<script src="jquery-2.1.0.js"></script>
7.2.2 节点树及节点间的关系
在 HTML 中,所有标签定义的内容都是节点,它们构成了一个 HTML 节点树,也称之为 HTML DOM 树。DOM 是 W3C(万维网联盟)的标准,其英文全称 Document Object Model,即文档对象模型。它定义了访问 HTML 和 XML 文档的标准。根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点。
- 整个网站文档是一个文档节点。
- 每个 html 标签对应一个根元素节点,即上例中的 html 标签,这属于一个跟元素节点。
- 节点内的文本是文本节点,比如 a 节点代表一个超链接,它内部的文本也被认为是一个文本节点。
- 每个节点的属性是属性节点,比如 a 节点有一个
href
属性,它就是一个属性节点。 - 注释是注释节点,在 HTML 中有特殊的语法会被解析为注释,但其也会对应一个节点。
所以,HTML DOM 将 HTML 文档视作树结构,这种结构被称为节点树,如图所示:
通过 HTML DOM,树中的所有节点均可通过JavaScript访问,所有HTML节点元素均可被修改,也可以被创建或删除。
节点树中的节点彼此拥有层级关系。我们常用父(parent)、子(child)和兄弟(sibling)等术语描述这些关系
7.2.3 选择器
在 CSS 中,我们使用 CSS 选择器来定位节点。
CSS 选择器还支持嵌套选择,各个选择器之间加上空格分隔开便可以代表嵌套关系,如 #container .wrapper p
则代表先选择 id
为 container
的节点,然后选中其内部的 class
为 wrapper
的节点,然后再进一步选中其内部的 p
节点。另外,如果不加空格,则代表并列关系,如 div#container .wrapper p.text
代表先选择 id
为 container
的 div
节点,然后选中其内部的 class
为 wrapper
的节点,再进一步选中其内部的 class
为 text
的 p
节点。这就是 CSS 选择器,其筛选功能还是非常强大的。
7.2.4 静态网页和动态网页
我们将最基本的 HTML 代码保存为一个 test.html 文件,然后把它放在某台具有固定公网 IP 的主机上,主机上装上 Apache 或 Nginx 等服务器,这样这台主机就可以作为服务器了,其他人便可以通过访问服务器看到这个页面,这就搭建了一个最简单的网站。
这种网页的内容是 HTML 代码编写的,文字、图片等内容均通过写好的 HTML 代码来指定,这种页面叫作静态网页。它加载速度快,编写简单,但是存在很大的缺陷,如可维护性差,不能根据 URL 灵活多变地显示内容等。例如,我们想要给这个网页的 URL 传入一个 name
参数,让其在网页中显示出来,是无法做到的。
因此,动态网页应运而生,它可以动态解析 URL 中参数的变化,关联数据库并动态呈现不同的页面内容,非常灵活多变。我们现在遇到的大多数网站都是动态网站,它们不再是一个简单的 HTML,而是可能由 JSP、PHP、Python 等语言编写的,其功能比静态网页强大、丰富太多了。此外,动态网站还可以实现用户登录和注册的功能。
7.3 爬虫的基本原理
7.3.1 抓取数据类型
html网页
- 文字、数值
- 下载多媒体,如图片、视频等
JSON数据