预备知识

1 HTTP协议

几乎所有的网站都使用 HTTP协议来通信,而爬虫的主要工作就是从网页中提取信息,因此 HTTP协议是我们学习爬虫的过程中必须要掌握的协议之一。

最初 HTTP协议用来在客户端和服务器之间传输文本数据,现在 HTTP协议已经支持在客户端和服务器之间传输文本、图片、音频、二进制文件等数据。需要说明的是 HTTP协议不负责数据的传输,而是负责标记数据的类型、数据的长度,这样客户端在收到响应之后才能正确地读取和解析数据,其中的细节后面会讲到。

现在我们先来看一下一个普通的 HTTP请求是什么样的:

1.1 请求方法

HTTP请求方法有很多种,包括 GET、POST、DELETE、PUT、OPTION、CONNECT等,不过对于爬虫来说我们只要了解 POST方法和 GET方法就能应付绝大多数场景。

POST的方法主要用于提交表单和请求数据的场景,比如登录、上传文件等。GET方法主要用于请求网页和资源,比如加载静态网页、下载文件等。POST和 GET的主要区别在于,POST的参数一般在报文体中,而 GET的参数一般在请求 URL中。

但这并不是强制的,实际上两种方法的参数都可以在 URL 和报文体中。之所以这样区分一个是因为使用习惯,另一个是因为 URL中最多只能存放 64KB的数据,所以当参数数据量较大时只能放在报文体中。还有一个原因是 URL一般会显示在浏览器的地址栏中,因此用户可以很容易地修改 URL中的参数,所以对于一些比较敏感的参数一般使用 POST方法提交。

1.2 报文头

报文头根据请求和响应也可以叫做请求头和响应头。报文头中的信息主要有文件格式、编码方式、语言你、cookie、user-agent、referer等。大多数反爬手段都利用了报文头中的信息,所以爬虫的第一步就是构造请求头。在构造请求头之前我们先来了解一下报文头中都有哪些字段。

  • User-Agent:这个字段用来表示用户所使用的操作系统和浏览器版本,很多网站根据这个来识别简单的爬虫(因为大多数的请求库默认不设置 user-agent或者设置的 user-agent一看就不是浏览器)。
  • Referer:这个字段的值是用户的来源网页,即用户请求当前网页之前正在访问的网页,只有当用户是点击链接跳转时才浏览器才会添加这个字段,如果用户直接把地址粘贴到地址栏的话这个字段为空。
  • Cookie:cookie一帮用来保存会话状态,对于需要登录才能爬取的网站需要加上这个字段才能正常爬取。但是这并不是万能的,直接从浏览器复制的方法只是最简单的方法,对于一些网站会失效(淘宝、知乎等)。
  • Content-Type:Content-Type传输的数据类型。这个字段很重要,在提交表单和上传文件的时候都会用到,现在我们先了解一下,后面用到的时候再详细说。
  • 其他的字段和爬虫关系不大,比如 accept-language、accept-encoding、content-length等,这些字段只要稍微了解一下就行。

1.3 报文体

报文体分为请求的报文体和响应的报文体。请求的报文体用来携带数据(POST参数、文件内容等),响应的报文体一般是服务器返回的网页代码、下载的文件内容等。报文体我们不用特别关注。

2 HTML文档

所有的网页都使用 HTML来组织内容,我们要爬的数据也包含在 HTML代码中,要想快准狠地把数据从 HTML中提取出来了解一下 HTML是很有必要的。

2.1 HTML标签

任何一个 HTML文件都是由互相嵌套的标签组成的,这些标签大部分都有一个开始和一个结尾,示例如下:

<div>
    <span>我是要提取的数据</span>
</div>

尖括号中间的标识符是标签的名字,标签的开始是由两个尖括号和标签名字组成,标签的结束也是由两个尖括号和标签名字组成,但是在标签名字前面有一个反斜杠表示标签结束了。HTML文档就是由若干个标签互相组合而成的。

标签之间有嵌套关系,如果一个标签 A在另一个标签 B的开始和结束之间,那么我们称标签 A是标签 B的子元素,反过来标签 B是标签 A的父元素。如果他们之间没有其他的元素,那么我们可以进一步称标签 A是标签 B的直接子元素,标签 B是标签 A的直接父元素。

2.2 标签属性

标签属性语法如下:

<div id="id_div" class="example"></div>

标签属性在爬虫中可以用来定位目标标签,比如通过 CSS选择器或者 Xpath提取标签时就要用到标签的属性,这个我们放到 Xpath中讲。

2.3 标签类型

标签有很多种,不同的标签有不同的作用,自然也就携带不同的数据。我挑几个常用的列出来:

  • a:a标签是网页中的链接,点击 a标签可以跳转到指定的链,这个链接的值就保存在 a标签的 herf属性中。另外 a标签也可以用来作为页内跳转使用,这时 herf属性的值就是某个标签的 id。
  • div:div标签没有特殊的用途,也没有特殊的属性。一般把 div标签用来布局。
  • table:table标签用来展示表格数据,它的子元素一般是 tr和 td,tr表示单元行,td表示单元格。数据一般都在 td中。需要注意的是,浏览器在渲染时可能会在 table和 td、tr之间添加 tbody,而 tbody本来是不在 HTML代码中的。
  • img:img标签用来展示图片。img的 src属性就是图片链接。