以前写过一篇博客如何爬取微博热搜的前50条,当时是从代码出发理解爬虫实现的过程。这篇博客主要讲一下HTTP的基本知识,知道从浏览器中输入网址到我们获取网页内容的过程中发生了什么,有助于进一步了解爬虫的基本原理。
1. URI、URL和URN
先放上这三个名词的定义:
- URI:Uniform Resource Identifier 统一资源标志符
- URL:Uniform Resource Locator 统一资源定位符
- URN:Uniform Resource Name 统一资源名称
URI是一个抽象定义,只要能定位到一个资源,都叫做URI。
URL和URN都是URI的子集,简单来说,URL用地址定位资源,URN用名称定位资源。只是后来URN在互联网中使用非常少,导致现在几乎所有的URI都是URL,因此我们可以将一般网页链接称之为URI或者URL(后者用的最多)。
那么URL或者URI具体指什么呢?
举个例子,本站图标地址https://www.shelven.com/tuchuang/bitbug_favicon.ico
,通过这个地址可以访问到一只32*32像素大小的可爱小猫,通过这个地址URL/URI指定了它的访问方式,包括了访问协议https,访问路径和资源名称bitbug_favicon.ico。这个访问资源可以是一个图片,一个CSS文档,一个HTML页面等等。
以HTTPS协议访问web服务器为例,拆解一下完整的URL结构:
https://user:password@www.shelven.com:443/tuchuang/bitbug_favicon.ico
- 协议:URL开头部分必须是协议类型,常见的https、http、ftp和mailto,指明浏览器应当使用的访问方法,用//做分隔符
- 用户名/密码:user:password这部分可以省略
- 域名:我这里域名是
www.shelven.com
,我们在发送请求前会向DNS服务器解析这个域名的ip地址,域名只是方便我们人类记忆的,计算机访问的最终都是ip地址。当然,如果你能记得住ip地址也可以直接输入。 - 端口:用来区分不同网络服务(web服务、ftp服务等),和域名之间用冒号:分隔,端口不是URL必须的部分,http默认端口80,https默认端口443,ftp默认端口21。
- 文件路径/文件名:从域名第一个
/
到最后一个/
之间是虚拟目录;从域名最后一个/
到?
部分是文件名,没有?
则是到#
为止,都没有则是从最后一个/
一直到结束都是文件名部分。文件名是可以缺省的。
2. 超文本
超文本(Hyper Text, HT)是用超链接的方法,将不同空间文字信息组织在一起的网状文本。
举个例子,浏览器中看到的网页就是超文本解析而来的,网页本身就是一个文本文件,而超文本指这种文件既可以包含文本信息,又可以包含图片、视频、链接等非文字信息。
网页的源代码是一系列HTML(Hyper Text Markup Language, 超文本标记语言)代码,里面包含了一系列标签(尖括号<>包围的关键词,一般成对出现)和属性值。在浏览器中打开任意一个页面,按F12就可以打开浏览器的开发者工具,选择元素(Elements)选项卡就可以看到当前网页的源代码,而这些源代码都是超文本。
红框框住的左上角箭头,点击以后可以在页面中用鼠标悬停选中元素,右边对应的源代码部分会高亮,方便我们进行元素审查。
这里顺便记录下HTML常用的标签和属性:
标签名 | 用法 |
---|---|
基本结构标签 | |
HTML标签(根标签) | <html></html> |
文档头标签 | <head></head> |
文档标题标签(网页标题) | <title></title> |
文档主体标签(页面内容) | <body></body> |
列表标签 | (这里因为渲染问题&emsp无法显示空格…知道HTML有缩进的意思就行) |
无序列表 | <ul type=”disc/circle/square”>  <li>条目内容</li> </ul> |
有序列表 | <ol type=”1/a/A/i/I”>  <li>条目内容</li> </ol> |
定义列表 | <dl>  <dt>列表标题标签</dt>  <dd>具体列表项</dd> </dl> |
表格标签 | |
表格标签(tr为行) | <table>  <tr>   <td>单元格内容</td>  </tr> </table> |
常用标签 | |
标题标签(h1-h6) | <h1>一级标题</h1> |
段落标签 | <p>这里是内容</p> |
字体标签 | <font size=”10” color=”black” face=”微软雅黑”>你好</font> |
换行标签 | <br/> |
水平线标签 | <hr size=”10” color=”red” width=”50%” align=”left”/> |
盒子标签div | <div>div标签内容独占一行</div> |
盒子标签span | <span>span标签内容一行可以多个</span> |
图片标签 | <img src=”地址” width=’”宽度” height=”高度”></img> |
超链接标签 | <a href=”跳转网址” target=”窗口弹出方式”></a> |
注释标签 | <!– 注释内容 –> |
还有表单标签<form></form>等等,太多了这里就不一一详细说了,如果以后有必要再出一个详细的HTML笔记,现在只要看到这些标签心里有个数就行,真正要做前端再去详细探究。
3. 协议
前面说URL的开头必须指明协议类型,常用的是ftp(文件传输协议)、http(超文本传输协议)、https(http的安全版)、mailto(电子邮件协议)和smb(通信协议)。不需要对所有协议了如指掌,前三中协议是我们日常用的最多的,http和https是我们访问网站web服务所必须的,爬虫也可以通过这两种协议伪装成浏览器访问,从而抓取我们需要的页面。
HTTP(Hyper Text Transfer Protocol, 超文本传输协议)就是一个简单的请求-响应协议,运行在TCP之上,指定客户端发送什么样的消息以及得到什么响应,服务器端实现程序有httpd
(本站就是用的这个)和nginx。HTTPs(Hyper Text Transfer Protocol over Secure Socket Layer)以安全为目标的HTTP通道,说白了就是安全版HTTP,在HTTP下加入SSL层,传输内容经过SSL加密。
本站建站之初,我当时绕了一大圈才签下来SSL证书……HTTPS的安全基础是SSL,主要作用是建立一个信息安全通道,保证数据传输的安全;确认网站的真实性,使用https的网站可以通过浏览器地址栏的锁头标志,查看网站认证的真实信息。
有些网站使用了HTTPs协议但还是会被浏览器提示不安全,那有可能是证书过期了,或者颁发CA证书的机构不是被信任的,这样就会提示”您的连接不是私密连接“。而要用爬虫爬取这种页面的话,需要设置忽略证书,否则会提示SSL证书连接错误。
4. HTTP请求过程
我们在浏览器中输入一个 URL,回车之后便会在浏览器中观察到页面内容。这个过程是浏览器向网站所在的服务器发送了一个请求,网站服务器接收到这个请求后进行处理和解析,然后返回对应的响应,接着传回给浏览器。响应里包含了页面的源代码等内容,浏览器再对其进行解析,将网页呈现出来。
以本站作为演示,打开浏览器,按下F12进入开发者工具,点击网络(Network)选项;搜索框输入https://www.shelven.com
,回车。观察整个过程中发生了怎样的网络请求。
看下第一个网络请求www.shelven.com,各列的含义如下:
- 名称name:请求的名称,返回的每一条都是对应的数据包
- 状态status:响应的状态码,通过状态码判断发送请求之后是否得到正常的响应
- 类型type:请求的文档类型,这里是返回document,内容就是一些html代码
- 发起程序initiator:请求源,标记是哪个对象或者进程发起的请求
- 大小size:从服务器下载的文件和请求资源的大小
- 时间time:发起请求到获取响应的总时间
- 时间线waterfall:网络请求的可视化瀑布流
点击具体条目可以看到更详细的信息。
主要看三个部分,常规(general)、响应头(Response Headers)和请求头(Request Headers)。常规部分是总的数据包概括。请求头带有请求信息,例如Cookies、user-agent等信息,服务器会根据请求头内的信息判断请求是否合法,进而作出对应的响应。响应头就是响应的一部分,包含了服务器的类型、文档类型、日期等信息,浏览器接受到响应后,会解析响应内容,进而呈现网页内容。
5. 请求
请求指的是从客户端到服务器端的请求消息,发给服务器的请求称为请求报文,可以分为请求行(request line),请求头(request header)和请求体(request body)。
5.1 请求行
请求行中包括了请求方法,请求协议和版本。
以百度首页为例:
小框框起来的地方为请求行,可以看到百度首页的请求方法为get,请求协议为HTTP版本1.1
常见的请求方法有两种:GET和POST
- GET 请求中的参数包含在URL里面,数据可以在URL中看到,而POST请求的URL不会包含这些数据,数据是通过表单形式传输的,会包含在请求体中。
- GET 请求提交的数据最多只有1024字节,而POST方式没有限制。
因为GET请求方式不涉及和数据库的交换,所以我们浏览网页用的都是GET请求;如果要在一个网站登录,就需要提交用户名和密码的表单,这个时候用的就是POST请求。还有一个重要的因素,GET方式请求的数据是在URL中完全暴露的,所以也不会用GET方式发送请求,不然容易造成密码泄露。
其他请求方法在前面一篇爬虫博客有提到,这里列个表格:
方法 | 描述 |
---|---|
GET | 请求页面,并返回页面内容 |
POST | 大多用于提交表单或上传文件,数据包含在请求体中 |
HEAD | 类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头 |
PUT | 从客户端向服务器传送的数据取代指定文档中的内容 |
DELETE | 请求服务器删除指定的页面 |
CONNECT | 把服务器当作跳板,让服务器代替客户端访问其他网页 |
OPTIONS | 允许客户端查看服务器的性能 |
TRACE | 回显服务器收到的请求,主要用于测试或诊断 |
表格参考:HTTP 请求方法 | 菜鸟教程 (runoob.com)
5.2 请求头
请求头是用来说明服务器使用的附加信息的,上面那个百度首页例子的大框框住部分就是请求头的信息。
同样列个表格记录下常用的头信息。
头信息 | 描述 |
---|---|
Accept | 请求报头域,用于指定客户端可接受哪些类型的信息 |
Accept-Language | 指定客户端可接受的语言类型 |
Accept-Encoding | 指定客户端可接受的内容编码 |
Host | 指定请求资源的主机IP和端口号 |
Cookie | 而存储在用户本地的数据,主要功能是维持当前访问会话 |
Referer | 标识请求是从哪个页面发过来的,服务器可以拿来做来源统计、防盗链处理 |
User-Agent | 服务器识别客户使用的操作系统及版本、浏览器及版本等信息,爬虫伪装浏览器必备 |
Content-Type | 请求的数据类型信息HTTP Content-type 对照表 (oschina.net) |
5.3 请求体
请求体承载POST请求中的表单数据,GET请求的请求体为空。
这里以登录github捕获的请求体为例:
登录的时候填写的用户名和密码信息,提交的时候就会以表单形式提交给服务器,这个时候可以看到请求头中的Cotent-Type为application/x-www-form-urlencoded,表示以表单数据的形式提交给服务器。可以设置不同的Cotent-Type,以不同的方式提交数据,如果在做爬虫的时候要构造POST请求,需要注意一下使用正确的Cotent-Type(类型/子类型),不然可能会提交后无法正常响应。
Cotent-Type | 数据提交的方式 |
---|---|
application/x-www-form-urlencoded | 表单数据 |
multipart/form-data | 表单文件上传 |
application/json | 序列化JSON数据 |
text/xml | XML数据 |
application/pdf | pdf格式 |
application/octet-stream | 二进制流数据(如常见的文件下载) |
6. 响应
和请求类似的,服务器进行HTTP响应也是分为三个部分:响应状态行,响应头和响应体
6.1 响应状态行
回到之前百度首页的例子,我们点开百度首页审查元素,这次点开响应那一栏查看源。
小框框起来的地方是响应状态行,我们可以看到响应的协议版本是HTTP/1.1,响应状态码是200,说明返回正常。
响应状态码其实并不陌生,顾名思义表示服务器的响应状态。200说明服务器正常响应返回正常数据,经常能看到404报错,代表的是页面未找到,403表示服务器拒绝执行请求,503代表服务器不可用,301代表网页被永久转移到其他URL。
因为状态码非常多,这里就记录一下状态码的分类,详细状态码列表可以参考HTTP 状态码 | 菜鸟教程 (runoob.com)
分类 | 分类描述 |
---|---|
100-199 | 信息响应,服务器收到请求,需要请求者继续执行操作 |
200-299 | 成功响应,操作被成功接收并处理 |
300-399 | 重定向,需要进一步的操作以完成请求 |
400-499 | 客户端错误,请求包含语法错误或无法完成请求 |
500-599 | 服务器错误,服务器在处理请求的过程中发生了错误 |
6.2 响应头
上面例子中红色大框框住的部分就是响应头,包含服务器对请求的应答信息。
响应头主要有如下的信息:
头信息 | 描述 |
---|---|
Date | 标识响应产生的时间 |
Last-Modified | 指定资源的最后修改时间 |
Content-Encoding | 指定响应内容的编码 |
Server | 服务器的信息,比如名称、版本号 |
Content-Type | 返回的数据类型信息 |
Set-Cookie | 设置 Cookies,下次请求会携带这个cookies |
Expires | 指定响应的过期时间 |
6.3 响应体
响应体就是响应的内容,请求网页的时候响应体就是对应的HTML源代码,请求一张图片,响应体就是返回的二进制数据。爬虫就是通过请求到网页后,解析响应体中的内容(有的时候是HTML代码,有的时候是JSON数据等等,这两者比较常见),然后从中提取我们要的信息。
在edge浏览器中,进入开发者工具,点击network选项,选中需要解析的项目名称,点击响应就可以看到返回的响应体数据了。
以上暂时总结这么多HTTP的基础,参考了相当多的内容,后面做爬虫练习自然会用到。