网络爬虫原理与实践:基于C#语言
上QQ阅读APP看书,第一时间看更新

1.1 网络基础

本节将介绍与爬虫密切相关的网络知识,主要内容包括:网络的基本概念、HTTP和会话机制。如果你已经掌握了这些知识,可以跳过本节。

1.1.1 网络的基本概念

1.互联网与网络协议

计算机网络由若干节点(Node)和连接这些节点的链路(Link)组成。网络中的节点可以是计算机、集线器、交换机等设备。网络之间可以通过路由器互连起来构成覆盖范围更大的计算机网络——互联网(internet)。互联网的模型结构如图1-1所示。

图1-1 互联网示意图

因特网(Internet)是目前世界上覆盖范围最广、规模最大、资源最丰富的互联网。因特网采用TCP/IP协议族作为信息通信规则,提供包括WWW、FTP、E-mail、Telnet在内的多种服务。

计算机必须遵循一定的网络协议才能进行正常的信息传输和数据交换。在计算机网络中,通信双方进行信息传输时所遵循的规则、标准或约定即网络协议(简称协议)。网络协议明确规定了交换数据的格式以及相关的同步问题,为计算机在网络中有条不紊地进行数据交换提供了保证。网络协议一般由语法、语义和时序3个要素组成:

□ 语法:规定了数据与控制信息的结构或格式。

□ 语义:规定了需要发出何种控制信息、完成何种动作以及做出何种响应。

□ 时序:规定了事件的实现顺序。

网络协议通过网络协议软件来实现。连接在网络上的计算机要执行网络任务,首先必须安装网络协议。由于计算机网络协议非常复杂,为了简化实现并提高设计效率,人们采用分层的方法来研究它,从而形成了分层的网络体系结构。因特网采用的TCP/IP体系结构及各层的关键协议如表1-1所示。

表1-1 TCP/IP体系结构及各层的关键协议

IP(Internet Protocol,网际协议)在整个TCP/IP协议族中处于核心地位,主要用于解决不同网络之间的互连问题,是构成互联网的基础。IP位于TCP/IP模型的网际层,对上承载各种传输层协议(如TCP、UDP等),对下支持多种网络接口(如Ethernet等)。

2.网络地址与端口号

TCP/IP规定:网络上的每个设备都必须至少具有一个独一无二的IP地址,这就像信件上必须注明收件人地址,邮递员才能将信件送到一样。因此,每个IP数据包都必须包含目标设备的IP地址,才能够被正确转发到目的地。

说明:IP地址由ICANN(The Internet Corporation for Assigned Names and Numbers,因特网名称与数字地址分配机构)负责统一分配。我国用户可以向亚太网络信息中心(Asia Pacific Network Information Center, APNIC)申请IP地址。目前广泛使用的IPv4地址由32位二进制数组成。为便于识别,通常将IPv4地址表示为“点分十进制”(如220.181.38.149)。在下一代IP——IPv6中,IP地址包含128位二进制数(通常采用十六进制数表示)。

为了便于对IPv4地址进行管理,因特网对IP地址进行了分类,每一类地址由两个固定长度的字段组成。其中第一个字段是网络号(Net-Id),它标识主机或路由器所连接的网络;第二个字段是主机号(Host-Id),它标识网络中的一个主机或路由器。图1-2展示了分类IP地址的二进制结构。

因特网使用IP地址来唯一标识网络中的一台设备,但一台计算机可能运行着多个应用程序或服务,那么数据是如何正确地传输至同一台计算机的不同应用程序的呢?答案是可借助协议端口号(Protocol Port Number)来区分不同的程序。

图1-2 IP地址的分类

协议端口号简称端口号,是用来标识一台计算机上的特定网络应用的数字编号,其有效范围为0~65535。其中,0~1023为公认端口(Well Known Port)或系统端口,相对固定地分配给常用服务程序;1024~49151为注册端口(Registered Port)或登记端口,松散地绑定着一些服务;49152~65535为动态/私有端口(Dynamic/Private Port),供用户程序自由申请使用。表1-2列出了一些常用的公认端口号。

表1-2 常用的公认端口号

端口号通常与IP地址配合使用,端口号通过“:”连接在IP地址之后,表示该IP所指主机中某个特定的网络应用(服务)。例如,我们可以通过“http://220.181.38.149:80”访问百度首页,但通常省略默认端口号(80),将其简化为“http://220.181.38.149”。

3.域名与DNS

由于IP地址是一个固定长度的数字序列,不便于人类记忆(人们更擅长记忆那些有特定含义的字符串),因此有人提出了域名(Domain Name, DN)的概念。域名可以看作IP地址的别名,它由“.”分隔的标号序列组成。例如,可以使用域名“www.baidu.com”代替IP地址“220.181.38.149”。显然,前者更容易被记住。

域名中的各标号分别代表不同的域,域之间存在一定的层次结构,从右至左分别为顶级域、二级域、三级域等。例如,在“www.baidu.com”中,“www”为三级域名,“baidu”为二级域名,“com”为顶级域名。因特网中的基本域名结构如图1-3所示。

图1-3 因特网域名结构示意图

虽然域名便于记忆,但网络设备仍是基于IP地址进行数据转发的。为此,人们又设计了域名系统(Domain Name System, DNS)以实现域名到IP地址的映射,从而确保在使用域名的情况下也能够正常进行数据转发。因特网中的域名系统通过多个域名服务器来实现,其中最重要的是根域名服务器。由于历史和技术原因,全球共有13个根域名服务器(从a.rootservers.net到m.rootservers.net,分别对应13个IP)。每个根域名服务器又包含若干镜像,它们通过任播(Anycast)技术共享同一个IP,访问该IP的报文会被转发到就近的镜像服务器。目前,全球共有1000多个根镜像服务器。

我们通常认为域名与IP地址是一一对应的,这只是一种理想状态。实际上,一个IP地址可以对应多个域名,一个域名也可以被解析为多个IP地址。有些公司出于商业目的会注册多个域名,并指向同一个IP地址;有些门户网站为了负载均衡会将同一个域名解析到不同的Web服务器。顶级域名往往具有特定的含义(如表1-3所示)。

表1-3 主要的顶级域名及其含义

4.网络资源标识

网络资源是以数字化形式记录,以多媒体形式表达,以二进制数据存储,并通过计算机网络通信方式进行传播的信息内容集合。与传统信息资源相比,网络资源在数量、结构、分布、传播范围、载体形态、传递手段等方面都呈现出不同的特点。从资源形式来看,网络资源包括文本、图像、音频、视频、数据库等。

网络资源必须按照一定的规则进行准确标识,才能被访问和使用。URL(Uniform Resource Locator,统一资源定位符)是一种用于标识网络资源的技术规范。URL指定了某个资源在因特网中的位置以及访问方式,其基本结构如下:

<协议>://<主机>:<端口>/<路径>

□ <协议>:指出采用什么协议来获取该网络资源(形如http、ftp等)。

□ “://”:固定格式,位于<协议>之后、<主机>之前。

□ <主机>:指出网络资源存储在哪台主机上,可使用域名或IP地址表示。

□ “:”:固定格式,位于<主机>之后、<端口>之前。

□ <端口>:指明访问服务器上的哪个网络应用端口号。

□ <路径>:指明网络资源在服务器上的具体位置(可包含多级路径)。

以“http://github.com:80/img/favicon.ico”为例,其协议类型为HTTP,访问目标是域名为“github.com”的主机;端口为80(HTTP默认端口,可省略);路径指向该主机img/目录下的favicon.ico文件。由此可见,通过URL可准确定位因特网中的某个资源。

说明:URL是URI(Uniform Resource Identifier,统一资源标识符)的子集,URL和URN(Uniform Resource Name,统一资源名称)共同构成了URI。URN只命名资源(如“ISBN:0451450523”标识一本书)而不说明如何定位。在因特网中,几乎所有的URI都是URL,我们通常将网络资源链接称为URL,也可称为URI。

5.万维网概述

WWW(World Wide Web,万维网)也称为Web,是因特网提供的核心服务之一。Web服务器使用HTML(HyperText Marked Language,超文本标记语言)将相关信息资源组织起来,HTML文档和相关资源在客户端展现为图文并茂的网页(Web Page)。

客户端和服务器之间采用HTTP进行数据传输,客户端向服务器发送资源请求,服务器将响应数据返回给客户端。Web服务器将多个相关网页有机地组织在一起,从而构成网站(Website)。用户可以通过超链接从一个页面跳转到另一个页面,这种跳转既可以在站点内部,也可以在不同站点之间(如图1-4所示)。

图1-4 万维网分布式服务

说明:当访问站点A的页面时,浏览器会将HTTP请求发送到站点A所在的服务器;若浏览器跳转到站点B的页面,则会向站点B所在的服务器发出请求。请求发送到哪里是由URL中的<主机>部分决定的,请求和响应的数据传输依靠下层的TCP来实现。

1.1.2 HTTP

1.HTTP与HTTPS

HTTP(HyperText Transfer Protocol,超文本传输协议)是由万维网协会(World Wide Web Consortium)和互联网工程任务组(Internet Engineering Task Force)共同制定的规范。HTTP应用广泛,几乎所有的Web应用都遵守该协议。HTTP基于TCP实现,它规定了浏览器如何向Web服务器发送请求,以及服务器如何将数据传送给浏览器。

HTTP的工作过程如图1-5所示。

1)Web服务器启动后不断监听TCP端口,以发现新的连接请求。

2)若服务器检测到连接请求,则与客户端建立TCP连接。

3)客户端基于前期建立的TCP连接,向万维网服务器发出资源请求。

4)服务器返回对客户端请求的响应,在数据传输完毕后释放TCP连接,结束本次服务。

说明:在HTTP服务模型中,客户端可以是Web浏览器,也可以是其他任何具有类似功能的应用程序(网络爬虫就属于此类)。HTTP服务器通常是一个Web服务器程序(如Apache、IIS等),其基本功能是接收客户端的请求并向客户端发送HTTP响应数据。

图1-5 HTTP工作过程

HTTP具有以下特点:

1)无连接,为每次HTTP请求建立单独的TCP连接,当服务器处理完客户端请求后就断开该连接。

2)无状态,HTTP对于事务处理没有记忆能力,有时会造成数据重复传输。

HTTPS(HyperText Transfer Protocol over Secure Socket Layer,超文本传输安全协议)是以安全为目标的协议。HTTPS本质上是在HTTP之下增加了安全套接字层(Secure Sockets Layer, SSL),HTTP与HTTPS的对比如图1-6所示。

图1-6 HTTP与HTTPS对比

安全套接字层主要提供以下服务:

1)加密数据以防止数据中途被窃取。

2)认证用户和服务器身份,确保数据发送到正确的目标。

3)维护数据的完整性,确保数据在传输过程中不被改变。

总之,HTTPS能够提供更安全的网络通信方式,并已广泛用于用户登录、交易支付等安全敏感的业务。

2.HTTP请求

HTTP请求(Request)主要包括以下要素:请求方法(Request Method)、请求网址(Request URL)、请求头(Request Header)和请求体(Request Body)。

在HTTP 1.0标准中定义了GET、POST和HEAD 3种请求方法,HTTP 1.1又增加了6种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE和CONNECT。其中GET和POST仍然是常用的请求方法,它们的区别如表1-4所示。

表1-4 GET与POST方法的对比

说明:GET方法的参数直接写在URL中,例如,在“http://hostname/list.html?page=2&size=10”中,“?”之后为参数部分,参数之间以“&”分隔,参数名和参数值以“=”连接。HTTP规范并没有对URL的长度进行限制,但大多数浏览器和服务器对此是有限制的。若登录时使用GET方法,用户名、密码等敏感信息就会暴露在URL中,造成隐私泄露,因此应当使用POST方法。此外,上传文件也应使用POST方法。

HTTP请求头可包含若干字段,用于描述客户端的状态,其目的是针对本次请求与服务器进行协商。常见的请求头字段如表1-5所示。

表1-5 常见的请求头字段

(续)

请求头中的大部分字段是可选的,但有时某些字段是必需的,比如采用POST请求方法时必须包含Content-Length和Content-Type字段。网络爬虫通常需要设置User-Agent等字段,将自己伪装成某种浏览器发送请求,否则可能会收到异常响应。GET方法不需要请求体,POST方法的请求体可采用多种数据格式(如表1-6所示)。

表1-6 请求体的数据格式

3.HTTP响应

HTTP响应(Response)是Web服务器对HTTP请求的回应,包括以下3个要素:响应状态码(Response Status Code)、响应头(Response Header)和响应体(Response Body)。

响应状态码表示服务器的响应状态,常见的状态码如表1-7所示。在网络爬虫的工作过程中,可以根据状态码来判断服务器状态,进而采取相应的措施。

表1-7 HTTP响应状态码

(续)

HTTP响应头描述服务器的状态以及响应体的相关属性,与请求头中的部分字段相呼应,是服务器与客户端协商的结果。常见的响应头字段如表1-8所示。

表1-8 响应头字段及其含义

紧跟在响应头之后的是响应体——响应的正文数据。响应体的数据类型由Content-Type字段指定:“text/html”表示HTML文档,“text/css”表示CSS文件,“application/x-javascript”表示JavaScript文件,“image/jpeg”表示JPEG格式的图片等。响应头通过Set-Cookie字段告诉浏览器将哪些内容存放在本地Cookie中。

在Firefox浏览器“开发者工具”中选择“网络”工具(如图1-7所示),刷新页面即可看到当前网页产生的HTTP请求,右侧会列出请求头和响应头的字段详情。

如图1-7所示,访问单个网页却引发了一系列的HTTP请求,这是因为网页不仅包含HTML文档,还有很多相关资源,如图像、CSS文件、JS代码等。这些资源的URL以各种形式嵌入HTML文档中,浏览器解析到这些资源后会引发新的HTTP请求。

图1-7 HTTP请求头和响应头实例

1.1.3 会话机制

有些Web应用场景不需要登录(如浏览新闻、百度搜索等),另外一些场景则需要登录(如网上购物、论坛发帖等)。登录的目的是让服务器知道你是谁,进而获得差异化服务。例如,用户A在登录某论坛后,只能查看自己的用户信息、修改自己的密码,所发的帖子也不能记在其他用户的名下。

客户端与Web服务器连续发生的一系列交互过程被称为一次会话,这个过程类似于两人之间的一次通话。无状态的HTTP本身并不支持会话,会话的关键在于服务器如何识别用户身份,这可以借助Cookie或Session技术来实现。Cookie和Session是两种不同的会话管理方式,前者主要在客户端记录用户信息,后者主要在服务器中记录用户信息。

1.Cookie机制

基于Cookie的会话机制如图1-8所示,服务器在验证用户身份后,会要求客户端额外保存一些数据——Cookie,其中包含一个相当于“会话ID”的信息,此信息同时被保存到服务器的后台数据库中。当用户携带Cookie信息再次提交请求时,服务器可以根据“会话ID”识别用户身份。

图1-8 基于Cookie的会话机制

如图1-9所示,当我们成功登录“网易通行证”时,服务器所返回的响应头中包含一些名为Set-Cookie的字段,这些字段就是服务器向客户端颁发的通行证(Cookie)。

图1-9 HTTP响应中的Set-Cookie字段

每个Set-Cookie字段包含多个键值对,第一个键值对表示Cookie的名称(name)和取值(value),其他键值对则表示Cookie的一些特定属性(如表1-9所示)。

表1-9 Set-Cookie字段中的属性

如图1-10所示,登录网易后再次向服务器发送请求,就会在请求头中携带所保存的Cookie信息(通过Cookie字段),服务器可以据此识别用户身份。

图1-10 HTTP请求头中的Cookie字段

响应头中可以有多个Set-Cookie字段,但请求头中通常只有一个Cookie字段(其中包含多个键值对)。Cookie数据在默认情况下会被保存,但用户也可以设置浏览器禁用某些网站的Cookie。不同浏览器保存Cookie的方式有所不同:IE浏览器直接将其保存为文本文件,Firefox浏览器则将其保存到SQLite数据库中。

2.Session机制

在Cookie机制中,会话数据存放在客户端,服务器只保存会话ID。虽然Cookie简单高效,但也存在一些不足:

1)浏览器对Cookie的数量和大小都有限制,难以表示复杂的会话信息。

2)Cookie数据保存在客户端,安全性较差。

针对上述不足,人们又提出了Session机制(Session本身就是“会话”的意思)。

与Cookie相反,Session机制中的会话数据存放在服务器中,会话ID则以Cookie的形式存放在客户端。Session的基本工作步骤如下:

1)服务器创建Session对象。当某个客户端初次访问服务器时,服务器将为其创建一个Session,并生成一个与此Session相关联的Session ID。服务器将Session ID与本次响应信息一并返回给客户端。

2)客户端再次请求服务器。当客户端再次访问某服务器时,会将服务器前期返回的Session ID信息与请求信息一起发送给服务器。

3)服务器响应客户端请求。服务器收到客户端的请求消息后,首先检查客户端的请求消息里是否包含Session ID,若包含则说明前期已为该客户创建过Session;服务器可根据Session ID将会话信息检索出来并使用,若检索不到则新建一个Session。

4)结束Session。当客户端要求结束本次会话,或者服务器长时间没有收到从该客户端发来的请求时,则结束本次会话。会话结束后,服务器将删除本次会话数据。

Session机制的优势在于:

1)数据容量更大,不受浏览器的限制。

2)数据类型更丰富,可使用复杂内存对象。

3)会话控制更灵活,服务器能够随时掌握会话状态。

4)数据安全性更高,不易被盗取利用。但是,Session机制会占用更多的服务器资源,同时需要Cookie配合才能实现。