第3章Web应用架构与协议 Web服务器存储了Web页面,按照一定的方式响应客户端的请求。理解Web服务器的工作原理,对于掌握和设计网络爬虫具有重要意义。本章简述了Web服务器的应用架构,重点对网站页面文件的组织与内容生成、HTTP协议、状态保持技术以及Robots协议进行了详细介绍。 3.1常用的Web服务器软件 3.1.1流行的Web服务器软件 常见的Web服务器软件有Apache、IIS(Internet Information Server)、Nginx、Lighttpd、Zeus、Resin、Tomcat等。 Apache是使用范围很广的Web服务器软件,是Apache软件基金会的一个开放源代码的跨平台网页服务器。它可以运行在几乎所有主流的计算机平台上。Apache的特点是简单、速度快、性能稳定。它支持基于IP或者域名的虚拟主机,支持代理服务器,支持安全Socket层(SSL)等。目前,互联网网站主要使用它做静态资源服务器,也可以做代理服务器转发请求,同时结合Tomcat等Servlet容器处理JSP等动态网页。Apache Web服务器软件的网站截图如图31所示。 图31Apache Web服务器软件的网站截图 Nginx是一个高性能的HTTP和反向代理服务器,国内使用Nginx作为Web服务器的网站也越来越多,其中包括新浪博客、网易新闻、搜狐博客等门户网站频道,在3万以上访问次数的高并发环境下,Nginx的处理能力相当于Apache的10倍。 Nginx Web服务器软件的网站截图如图32所示。 图32Nginx Web服务器软件的网站截图 IIS(Internet信息服务)是微软公司主推的Web服务器,IIS与Windows Server完全集成在一起,因此用户能够利用Windows Server和NTFS文件系统内置的安全特性建立强大、灵活且安全的Internet和Intranet站点。IIS Web服务器软件的网站截图如图33所示。 图33IIS Web服务器软件的网站截图 Tomcat是Apache软件基金会的Jakarta项目中的一个核心项目,由Apache、Sun和其他一些公司及个人共同开发。因为Tomcat技术先进、性能稳定,而且免费,所以深受Java爱好者的喜爱,并得到了部分软件开发商的认可,是目前比较流行的Web应用服务器。图34是Tomcat Web服务器软件的网站截图。 图34Tomcat Web服务器软件的网站截图 3.1.2在Python中配置Web服务器 Python 3提供了小型Web服务器软件的功能,可以很方便地进行Web页面的开发和测试。以Windows操作系统为例,具体过程如下: (1) 通过执行cmd,进入Windows控制台。 (2) 切换到Web服务器的虚拟根目录,也就是存放网页的根目录位置。 (3) 执行命令: python -m http.server 端口号 以下是一个例子,假设虚拟根目录是E:\xxx,则进入控制台后执行以下命令: C:\>e: E:\>cd xxx E:\xxx>python -m http.server 8080 那么,启动成功后会在控制台显示: Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ... 之后,可以在浏览器中输入http://localhost:8080/来浏览E:\xxx中的页面和文件,在浏览的过程中控制台默认地会输出每个点击访问记录,样例如下: 127.0.0.1 - - [05/Nov/2019 15:43:32] "GET / HTTP/1.1" 200 - 127.0.0.1 - - [05/Nov/2019 15:43:36] "GET /1.html HTTP/1.1" 200 - 127.0.0.1 - - [05/Nov/2019 15:43:46] "GET /20.html HTTP/1.1" 200 - 127.0.0.1 - - [05/Nov/2019 15:44:03] "GET /4.html HTTP/1.1" 200 - 127.0.0.1 - - [05/Nov/2019 15:44:12] "GET /ch.txt HTTP/1.1" 200 - 3.2Web服务器的应用架构 基于Web的互联网应用都离不开Web服务器,在门户网站、网络论坛、电子商务网站等典型应用中,核心部件都是Web服务器。Web服务器为互联网用户提供页面信息访问服务,基本的访问方式包括浏览信息、发布信息等形式。 3.2.1典型的应用架构 从应用架构的角度看,Web服务器与客户端构成一种Client/Server的技术体系。在实际应用中需要考虑网站内容的可管理性、网站的并发能力、容错能力以及网站的可维护性等许多问题。针对这些问题有不同的解决方案,由此产生出不同的应用架构。4种典型的应用架构描述如下。 1. Client/Server 最简单的Web应用架构是单纯的Client/Server架构,它也是其他架构的基础,如图35所示。其中,客户端可以是各种浏览器,也可以是爬虫程序。 在这个架构中,一方面,Web服务器作为存储器,各种HTML文件可以直接存储在Web服务器的硬盘上,根据用户的请求情况再访问这些文件; 另一方面,Web服务器也是一个执行机构,能够处理用户的请求。在网络爬虫技术中,这种应用架构适用于静态网页的处理,每一个静态网页对应硬盘上的一个文件。 2. Client/Server/Database 在很多Web应用中,并不能简单地从Web服务器的硬盘上读取HTML文件内容推送给用户,而是需要读取后台数据库或访问其他服务器。相应地,在Web应用的架构中就必须增加数据库服务器,如图36所示。 图35Client/Server 图36Client/Server/Database 在这个架构中,Web服务器上的HTML文件中通常存在一些动态脚本,这些脚本在用户请求时由Web服务器执行。在执行过程中访问数据库,获取数据访问结果,Web服务器再将执行结果编码成HTML,推送给客户端。在网络爬虫技术中,这种架构支持了动态网页的实现。也就是说,网页中的主体内容是来自于数据库或其他服务器,而不是直接存在Web服务器的HTML文件中。 3. Web服务器集群 互联网Web服务器提供了开放式服务,可能会有大量用户并发访问的情况出现。在这种情况下,为了保证用户访问的体验度和容错性,Web服务器通常需要进行高可用和负载均衡设计。 负载均衡就是根据某种任务均衡策略把客户端请求分发到集群中的每一台服务器上,让整个服务器群来均衡地处理网站请求。因此集群是这种应用架构的典型特征和核心之一,通常用多台Web服务器构成一个松耦合系统,这些服务器之间通过网络通信实现相互协作,共同承载所有客户端的请求压力。如图37所示的应用架构就是这种集群架构,整个集群对外来看是一台Web服务器。 图37Web服务器集群 在这种架构中,网络爬虫每次连接到网站的IP地址可能并不是固定的,因此如果网络爬虫进行了DNS缓存优化设计,就应当考虑到Web服务器集群的这种具体情况。 4. 虚拟主机 虚拟主机是另一种常见的Web应用架构,它是指在一台服务器里配置多个网站,使得每个网站看起来具有独立的物理计算机。虚拟主机的实现方法有以下3种。 (1) 基于IP地址的方法: 在服务器里绑定多个IP,配置Web服务器,把网站绑定在不同的IP上。当客户端或爬虫访问不同的IP地址时就得到不同网站的响应。 (2) 基于端口的方法: 不同网站共享一个IP地址,但是通过不同的端口实现对不同网站的访问。这时 客户端访问的URL的形式为“http://hostname:port/”,需要指定端口。 (3) 基于主机名的方法: 设置DNS将多个域名解析到同一个IP地址上,IP地址对应的服务器上配置Web服务端,添加多个网站,为每个网站设定一个主机名。因为HTTP协议访问请求头里包含有主机名(即host属性)信息,所以当Web服务器收到访问请求时就可以根据不同的主机名来访问不同的网站。 3.2.2Web页面的类型 从Web网页的组成结构看,一个标准的网页一般包含4个部分,即内容、结构、表现效果和行为。内容是网页中直接传达给阅读者的信息,包括文本、数据、图片、音/视频等; 结构是指Web页面的布局,对内容进行分类使之更具有逻辑性,符合用户的浏览习惯; 表现效果指对已经结构化的内容进行视觉感官上的渲染,例如字体、颜色等; 行为则是指网页内容的生成方式。 根据Web页面组成结构中的信息内容的生成方式,可以将Web页面分为静态页面、动态页面、伪静态页面三大类。静态型的 Web页面随着互联网的出现而出现,虽然目前有大量的交互式动态页面能很好地提升用户体验,但是由于静态页面除了Web服务之外,不需要其他服务的支持,对服务器的资源消耗少,所以这种类型的页面在现阶段仍然被广泛使用。动态型页面一般需要数据库等其他计算、存储服务的支持,因此需要消耗更多的服务端资源。Web服务器在响应爬虫命令请求时,不管是静态页面还是动态页面,服务器返回给爬虫的信息一般都是封装成为HTML格式。因此,对于页面解析器而言,在处理Web服务器响应信息时,只要处理HTML格式的内容就可以。 静态页面以HTML文件的形式存在于Web服务器的硬盘上,其内容和最终显示效果是事先设计好的,在环境配置相同的终端上的显示效果是一致的,并且这些内容、表现效果等由且仅由HTML、JavaScript、CSS等语言控制。因此,静态页面的内容、结构和表现效果是固定的,其行为也比较简单,即在制作网页时直接保存到硬盘文件。 从实际应用的角度看,目前互联网上大部分都是动态页面。动态页面是相对静态页面而言的,具有明显的交互性,能根据用户的要求和选择动态改变。动态页面的主要特征如下: (1) 页面内容是可变的,不同人、不同时间访问页面时,显示的内容可能不同。 (2) 页面结构也是允许变化的,但是为了提升用户浏览的体验,结构一般不会频繁改变。 (3) 在表现效果上,页面中不同部分的效果会随着内容的变化而变化。 (4) 页面行为是区别于静态页面最主要的特征,动态页面并不是直接把内容存储到文件中,而是要进一步执行内容生成步骤,通常的方式有访问数据库等。 除了静态页面和动态页面外,还有一类页面称为伪静态页面,这种页面的出现是为了增强搜索引擎爬虫的友好界面。伪静态页面是以静态页面展现出来,但实际上是用动态脚本来处理的。为了达到这个目的,伪静态页面技术通常采用404错误处理机制 或rewrite技术来实现将静态的URL页面请求转换成内部的动态访问,再将结果以同样的URL返回给用户。 伪静态页面的URL本质上可以理解成不带“=”的参数,是将参数转换成为URL中子目录的一部分。例如,某论坛中同一个帖子的伪静态页面地址及其对应的动态页面地址分别如下: http://****.com/htm_data/7/1985527.html http://****.com/read.php?fid=7&tid=1985527 其中,伪静态页面的htm_data后面的7以及1985527分别与动态页面地址的fid=7和tid=1985527对应。当服务器收到伪静态页面的URL地址请求后提取出URL中相应的部分,并作为动态参数构造动态请求,在执行完成后将结果返回给客户端。 3.2.3页面文件的组织方式 大量的Web页面文件在Web服务器中的组织管理方式对于提升页面的可维护性是非常重要的。下面以Tomcat为例来说明服务器的页面文件管理方式。 如图38所示,在D盘的Tomcat安装目录下有子目录webapps,该子目录是Tomcat规定的虚拟根目录。在该子目录下有aaa和bbb两个子目录,而aaa下还有一个子目录images。其中,aaa下有两个文件a1.html和a2.html,bbb下有一个文件b1.html,images子目录下有3个文件,分别为p1.gif、p2.gif、p3.gif。 假设按照Tomcat的默认端口8080,那么在浏览器中访问a1.html的URL是: http://127.0.0.1:8080/aaa/a1.html 其相应的结果如图39所示,页面中的图片在a1.html中是通过<img src="images/p1.gif">来获得。这里的“images/p1.gif”就表示在当前目录中访问images子目录下的p1.gif,而由于当前访问的是a1.html文件,当前目录就是aaa。 图38Tomcat的目录结构 图39a1.html的访问方式及效果 下面的HTML代码则展示了a1.html页面中超链接的3种写法,分别介绍如下。 (1) <p><img src="images/p1.gif"> <a href="a2.html"> a2</a></p> 采用相对链接,访问a2.html。 (2) <p><img src="images/p2.gif"> <a href="..\bbb\b1.html"> b1</a></p> 采用相对链接,访问b1.html,..表示上级目录,此处即为虚拟根目录。 (3) <p><img src="images/p3.gif"> <a href="http://127.0.0.1:8080/bbb/b1.html"> b1</a></p> 采用以http开始的完整URL绝对链接,访问b1.html。 从这个例子可以看出,对于爬虫来说,在获取a1.html页面之后要寻找其中的href超链接。对于绝对链接,只需要把 “href=”后面的字符串提取出来即可; 而对于相对链接,没有完整的http,单纯从这个href所指定的链接无法知道其真正的结果,需要进行超链接的转换。 为了简化相对路径的转换,在HTML语言中提供了<base>标签,用来指定页面中所有超链接的基准路径。例如,如果在a1.html中增加如下<base>标签: <base href="http://127.0.0.1:8080/aaa/" /> 那么就意味着该文件中的所有超链接都以根目录下的aaa子目录为当前目录。因此作为爬虫程序,也应当检查HTML文档中是否存在<base>标签。 视频讲解 3.3Robots协议 3.3.1Robots协议的来历 普通的Web网站提供了开放式的空间,用户只要通过浏览器即可直接访问,大部分新闻网站、机构主页都属于这种形式。另一种Web网站页面则提供有限的开放式空间,需要经过身份识别后进一步访问更多页面信息,最常用的方法是要求用户输入用户名和口令信息,验证通过后访问Web页面。这种Web网站典型的是在线购物、社交媒体等网站中的个人相关信息页面。 对于搜索引擎爬虫而言,可以畅通无阻地采集第一种形式的Web页面,也可以在适当配置后以动态页面的方式访问第二种类型页面。因此不管哪种类型的Web页面最终都可以被搜索引擎收录而永久存储,并提供给用户任意搜索。这个结果在一定程度上增加了网站被其他人了解的可能性,为网站带来一定的流量增加。但是另一方面,某些页面可能是临时性的,或者不希望永久地存储于搜索引擎中。 为了给Web网站提供灵活的控制方式来决定页面是否能够被爬虫采集,1994年搜索行业正式发布了一份行业规范,即Robots协议。Robots协议又称为爬虫协议、机器人协议等,其全称是Robots Exclusion Protocol,即“网络爬虫排除协议”。这一协 议几乎被所有的搜索引擎采纳,包括Google、Bing、百度、搜狗等公司。随着互联网大数据时代的到来,目前互联网上除了搜索引擎的爬虫外还存在大量的非搜索引擎爬虫,该协议也就成为各类爬虫行为的行业规范。 3.3.2Robots协议的规范与实现 网站通过Robots协议告诉爬虫哪些页面可以抓取,哪些页面不能抓取。该协议指定了某种标识的爬虫能够抓取的目录或不能抓取的目录,也就是访问许可策略。这些访问许可的定义写在一个名称为robots.txt的文件中,该文件需要放在网站的虚拟根目录中。它可以公开访问,即在浏览器中打开网站后,在网站首页的地址后面添加“/robots.txt”,如果网站设置了访问许可,按回车就可以看到网站的Robots协议,即robots.txt文件的内容。 robots.txt文件的具体约定如下: (1) 文件中包含一个或多个记录,每个记录由一个或多个空白行隔开。每个记录由多行组成,每行的形式为: <field>:<optionalspace><value><optionalspace> 指出了每个字段及其对应的值。字段名有UserAgent、Disallow、Allow,每个记录就是由这些关键词来规定爬虫的访问许可。 在一个记录中可以有多个UserAgent、多个Disallow或Allow。 (2) UserAgent: UserAgent的使用方式是UserAgent [agent_name],其中agent_name有两种典型形式,即*和具体的爬虫标识。例如 : User-Agent:* 表示所定义的访问许可适用于所有爬虫 User-Agent: Baiduspider表示所定义的访问许可适用于标识为Baiduspider的爬虫 一些常见的爬虫标识有Baiduspider、Baiduspiderimage、Baiduspidernews、Googlebot、YoudaoBot、Sogou web spider、Sosospider、EasouSpider等,从名字本身可以看出爬虫是属于哪个公司的。这些标识是爬虫自己确定的,并对外公开,例如百度的爬虫可以在“http://baidu.com/search/spider.htm”查到。 (3) Disallow或Allow: Disallow和Allow的使用方法相同,只是决定了不同的访问许可。这种访问许可是针对目录、文件或页面而言,即允许或不允许访问。Robots协议的默认规则是,一个目录如果没有显式声明为Disallow,它是允许访问的。 下面以Disallow为例进行说明。 Disallow的典型写法如下: Disallow:/ Disallow:/homepage/ Disallow:/login.php Disallow指定的字段值可以是一个全路径,也可以是部分路径,任何以该字段值开始的URL都会被认为是不允许访问的,例如 “Disallow:/help”就蕴含着不允许访问“/help.html”和“/help/index.html”等,而“Disallow:/help/”不会限制对 “/help.html”的访问,但是对“/help/index.html”是限制访问的。 接下来看一些典型的例子。 (1) https://www.taobao.com/robots.txt 摘录两个记录,分别表示该网站对Bingbot和360Spider的访问许可。可以看出,对于前者,除了8个许可访问外,其他都是不允许抓取的; 而对于360Spider,只有3个许可访问。 User-Agent: Bingbot Allow:/article Allow:/oshtml Allow:/product Allow:/spu Allow:/dianpu Allow:/oversea Allow:/list Allow:/ershou Disallow:/ User-Agent: 360Spider Allow:/article Allow:/oshtml Allow:/ershou Disallow:/ (2) https://www.baidu.com/robots.txt 摘录最后3个记录,前两个分别表示该网站对yisouspider和EasouSpider的访问许可。可以看出,除了8个不允许访问外,其他没有写的目录都是允许抓取的。最后一个记录表示除了前面定义的爬虫外,其他爬虫不允许访问整个网站。 User-Agent: yisouspider Disallow:/baidu Disallow:/s? Disallow:/shifen/ Disallow:/homepage/ Disallow:/cpro Disallow:/ulink? Disallow:/link? Disallow:/home/news/data/ User-Agent: EasouSpider Disallow:/baidu Disallow:/s? Disallow:/shifen/ Disallow:/homepage/ Disallow:/cpro Disallow:/ulink? Disallow:/link? Disallow:/home/news/data/ User-Agent:* Disallow:/ (3) http://www.xinhuanet.com/robots.txt 新华网的robots.txt文件非常简单,可以看出,它允许所有的爬虫抓取该网站的所有页面。实际上,这种做法等同于网站根目录下没有robots.txt文件。 # robots.txt for http://www.xinhuanet.com/ User-Agent:* Allow:/ 由此可见,Robots协议通过Allow与Disallow的搭配使用,对爬虫的抓取实行限制或放行。如果网站大部分是不允许爬虫抓取的,则可以像淘宝一样,定义允许访问的模式,其他的则不允许。反之,如果大部分是允许抓取的,则可以参考百度的做法,显式定义不允许访问的模式。结合自己网站的结构,选择合适的编写方法能够简化robots.txt文件。例如某个网站的根目录下有a1、a2、…、a10子目录,只允许爬虫抓取a10子目录,按照前面的叙述,写成下表左边的形式就比右边的形式要简洁得多。 User-Agent:* Allow:/a10/ Disallow:/a User-Agent:* Disallow:/a1/ Disallow:/a2/ Disallow:/a3/ Disallow:/a4/ Disallow:/a5/ Disallow:/a6/ Disallow:/a7/ Disallow:/a8/ Disallow:/a9/ 上述基本功能及书写方式得到了大部分搜索引擎爬虫的支持,除此以外,还有一些拓展功能。虽然它们的普及性还不是很广,但是随着行业规范意识的增强,在编写爬虫程序时了解这些拓展功能,对于设计更加友好的爬虫是非常有益的。这些拓展功能主要有通配符的使用、抓取延时、访问时段、抓取频率和Robots版本号。 (1) 通配符的使用: Robots中的许可记录允许使用通配符来表示Disallow或Allow的范围。这些通配符包括*、$,需要注意的是问号(?)并不作为一个通配符。通配符*代表0个或多个任意字符(包括0个)。$表示行结束符,用来表示至此结束,后面不跟其他任何字符。 它们的含义举例说明如下: Disallow:/pop/*.html 表示不允许爬虫访问/pop/目录下任何扩展名为.html的文件。 Disallow:/private*/ 表示不允许访问以private开头的所有子目录。 Disallow:/*.asp$ 表示不允许访问以.asp结尾的文件,这就排除了以.aspx结尾的文件。 (2) 抓取延时: 规定爬虫程序两次访问网站的最小时间延时(以秒为单位),实际上就是规定了爬虫页面抓取的最高请求频率。使用方法如下: Crawl-delay: 10 两次访问网站的最小时间延时为10秒。 (3) 访问时段: 某些网站可能存在业务高峰期,为了使服务器将更多资源分配给它的用户,不希望爬虫来抓取数据。这时可以在许可记录中增加一行: Visit-time: 0100-0500 表示允许爬虫在凌晨1:00到5:00访问网站,其他时间段不允许访问。 (4) 抓取频率: 这是用来限定URL读取频率的一个选项,使用方法如下: Request-rate: 40/1m 0100 - 0759 表示在1:00到07:59之间,以不超过每分钟40次的频率进行访问。 (5) Robots版本号: 用来指定Robots协议的版本号,也就是编写robots.txt文件时遵守的Robots协议版本。虽然版本号只是一个选项,但是如果增加这个字段,就会让爬虫程序在解析robots.txt文件时更加方便。 Robot-version: Version 2.0 指出了所使用的版本为2.0。 目前,上述拓展功能在各网站中的使用还不流行,一个例子是知乎的robots (https://www.zhihu.com/robots.txt),其针对EasouSpider的约定就包含了Requestrate、Crawldelay,也使用了通配符。 User-agent: EasouSpider Request-rate: 1/2 # load 1 page per 2 seconds Crawl-delay: 10 Disallow: /login Disallow: /logout Disallow: /resetpassword Disallow: /terms Disallow: /search Disallow: /notifications Disallow: /settings Disallow: /inbox Disallow: /admin_inbox Disallow: /*?guide* 视频讲解 3.4HTTP协议 超文本传输协议(Hyper Text Transfer Protocol,HTTP)是互联网上使用最为广泛的一种网络协议,所有的WWW文件都必须遵守这个标准。HTTP是基于TCP/IP协议的应用层协议,采用请求/响应模型。通过使用Web浏览器、网络爬虫或其他工具,客户端向服务器上的指定端口(默认端口为80)发送一个HTTP请求,服务器根据接收到的请求向客户端发送响应信息。 3.4.1HTTP版本的技术特性 自1991年第一个版本的HTTP协议HTTP 0.9正式提出以来,HTTP协议已经经过了3个版本的演化,目前大部分 网页使用HTTP 1.1作为主要的网络通信协议。 1. HTTP 0.9 HTTP 0.9是第一个版本的HTTP协议,发布于1991年。HTTP 0.9只允许客户端发送GET这一种请求,不支持请求头,因此客户端无法向服务器端传递太多消息。 该协议规定服务器只能响应HTML格式的字符串,即纯文本,不能响应其他的格式,该协议只用于用户传输HTML文档。服务器响应后,TCP网络连接就会关闭。如果请求的网页不存在,服务器也不会返回任何错误码。 2. HTTP 1.0 1996年,HTTP协议的第二个版本HTTP 1.0发布。HTTP 1.0是以HTTP 0.9为基础发展起来的,并且在HTTP 0.9 的基础上增加了许多新的内容。 (1) HTTP 1.0增加了请求方法。HTTP 1.0支持GET、POST、HEAD几种请求方法,每种方法规定的客户端与服务器之间通信的类型不同。 (2) HTTP 1.0扩大了可处理的数据类型,引入了MIME(Multipurpose Internet Mail Extensions)机制,除了纯文本之外,还可以传输图片、音频、视频等多媒体数据。 (3) 在处理TCP网络连接时与HTTP 0.9相似,但HTTP 1.0在请求头中加入了Connection: keepalive,要求服务器在请求响应后不要关闭TCP连接,实现TCP连接复用,可以避免Web页面资源请求时重新建立TCP连接的性能降低。 3. HTTP 1.1 HTTP 1.1是目前使用最广泛的HTTP协议版本,于1997年发布。HTTP 1.1与之前的版本相比,改进主要集中在提高性能、安全性以及数据类型处理等方面。 (1) 与HTTP 1.0最大的区别在于,HTTP 1.1默认采用持久连接。客户端不需要在请求头中特别声明(Connection:keepalive),但具体实现是否声明依赖于浏览器和Web服务器。请求响应结束后TCP连接默认不关闭,降低了建立TCP连接所需的资源和时间消耗。 (2) HTTP 1.1支持管道(pipelining)方式,可以同时发送多个请求。在发送请求的过程中,客户端不需要等待服务器对前一个请求的响应就可以直接发送下一个请求。管道方式增加了请求的传输速度,提高了HTTP协议的效率。但是,服务器在响应时必须按照接收到请求的顺序发送响应,以保证客户端收到正确的信息。 (3) HTTP 1.1添加了Host(请求头)字段。随着虚拟主机这种应用架构技术的发展,在一台物理服务器上可以存在多个虚拟主机,这些虚拟主机共享一个IP地址。HTTP 1.1在请求头中加入Host(请求头)字段,指出要访问服务器上的哪个网站。 4. HTTP 2 HTTP 2于2015年发布,在实现与HTTP 1.1完全语义兼容的基础上,它在性能上实现了大幅提升,但尚未真正应用。 (1) HTTP 2允许客户端与服务器同时通过同一个连接发送多重请求/响应消息,实现多路复用。HTTP 2加入了二进制分帧层,HTTP消息被分解为独立的帧,帧可以交错发送,然后再根据流标识符在接收端重新拼装,使得HTTP 2可以在一个TCP连接内 同时发送请求和响应。 (2) HTTP 2压缩大量重复的首部信息,提升通信效率。HTTP每一次通信都会携带首部,当一个客户端想从一个服务器请求许多资源时,可能会出现大量重复的请求头信息。特别是在HTTP 1.1中,请求头信息以纯文本的形式发送,大量重复的请求头信息重复传输对网络运输资源的消耗很大。 3.4.2HTTP报文 HTTP报文中存在着多行内容,一般由ASCII码串组成,各字段的长度是不确定的。HTTP报文可分为两种,即请求报文和响应报文。由于目前大部分网站使用HTTP 1.1或HTTP 1.0版本,所以这里的报文就以这两种为主进行介绍。 request Message(请求报文): 客户端→服务器端,由客户端向服务器端发出请求,用于向网站请求不同的资源,包括HTML文档、图片等。 response Message(响应报文): 服务器端→客户端, 服务器响应客户端的请求时发送的回应报文,可以是HTML文档的内容,也可以是图片的二进制数据等。 HTTP 1.1的请求报文和响应报文在形式上与HTTP 1.0版本相同,只是HTTP 1.1版本中添加了一些头部来扩充HTTP 1.0的功能。因此,本节中关于请求报文和响应报文的叙述适用于HTTP 1.0,也适用于HTTP 1.1。 1. 请求报文 HTTP规定请求报文由起始行、头部(headers)以及实体(entitybody)构成。HTTP规定的请求报文格式如下。 <method> <request-URL> <version> <headers> <entity-body> 第一行是报文的起始行,也称为请求行,由请求方法<method>、请求URL<requestURL>、协议版本<version>构成。HTTP 1.0和HTTP 1.1支持GET、POST、HEAD几种请求方法,每种方法规定了客户端与服务器之间通信的类型。 接下来是头部,也称为请求头,包含了客户端处理请求时所需要的信息。根据实际需要,请求头可以是多行的形式。服务器据此获取客户端关于请求的若干配置参数,例如语言种类信息、客户端信息、优先级等内容。头部本质来说是包含若干个属性的列表,格式为“属性名:属性值”。例如“AcceptLanguage: zhCN”,将zhCN值赋给AcceptLanguage属性,表示客户端可接受的语言为简体中文。 请求头之后是回车换行符,表示请求头的结束。 请求头结束标志之后是请求报文的实体<entitybody>,也称为请求体,是传输的内容构成。请求体通过“param1=value1¶m2=value2”的键值对形式将要传递的请求参数(通常是一个页面表单中的组件值)编码成一个格式化串。 下面是一个向服务器传递name和password参数的请求体实例。 name=Jack&password=1234 值得注意的是,在使用GET和HEAD方法请求网页时没有请求体。其请求参数表现在请求行,附加在URL后面,使用“?”来表示URL的结尾和请求参数的开始。例如下面的命令行,表示客户端使用协议HTTP 1.0请求网页example.html,请求方法为GET。 GET /example.html? name=Jack&password=1234 HTTP/1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) Accept: text/html 这种方式可传递的参数长度受限。HEAD与GET方法的区别在于,服务器端接收到HEAD请求信息只返回响应头,不会返回响应体; 而使用POST方法请求时,客户端给服务器提供的信息较多,其请求数据都封装在请求体中。 2. 响应报文 与请求报文类似,HTTP响应报文由起始行、头部(headers)以及实体(entitybody)构成。HTTP 1.0和HTTP 1.1规定的响应报文格式如下。 <version><status><reason-phrase> <headers> <entity-body> 与请求报文的区别在于第一行,请求报文的起始行也称为响应行,由协议版本、状态码、原因短语构成。状态码为表示网页服务器HTTP响应状态的3位数字,客户端或爬虫可从状态码中得到服务器响应状态,后续将对状态码进行详细介绍。原因短语为状态码提供了文本形式的解释。例如下面的命令为服务器响应行,以“200 OK”结束,表明响应操作成功。 HTTP 1.0 200 OK 报文的响应行之后是响应头,包含服务器响应的各种信息,其结构与请求头一致,都是“属性名:属性值”的格式。 报文的<entitybody>部分是响应体,响应体是HTTP要传输的内容。根据响应信息的不同,响应体可以是多种类型的数据,例如图片、视频、CSS、JS、HTML页面或者应用程序等。如果客户端请求的是HTML页面,则响应体为HTML代码。客户端依据响应头中ContentType的属性值对响应体进行解析,如果属性值与响应体不对应,客户端可能无法正常解析。 以下是一个响应报文的例子,表示向客户端成功响应了text/plain类型的文本。 HTTP/1.0 200 OK Content-Type: text/plain <html> <body>example</body> </html> 3.4.3HTTP头部 在HTTP的请求报文和响应报文中都有头部信息块,其中的每个记录具有“属性名:属性值”的形式。图310、图311分别是请求“http://www.fudan.edu.cn/2016/index.html”页面时从浏览器的开发者模式下的截图,其中包含了请求头和响应头信息。两个图中除了第一行的请求行和响应行外,其他都是头部信息。 图310请求头信息块 图311响应头信息块 从图中可以看出,一些属性在爬虫程序设计中是非常重要的,例如UserAgent、Accept、AcceptLanguage、Cookie、ContentType ,可以直接在程序中填写相应的属性名和属性值来设置爬虫的行为和特征。 属性名可以归纳为三大类,即请求头和响应头都可以使用的属性,以及请求头和响应头独有的属性。完整的头部属性名可以在 Wikipedia网站的List_of_HTTP_header_fields页面中查阅(https://en.wikipedia.org/wiki/List_of_HTTP_header_fields),一些常用的属性名说明如下。 1) Accept Accept请求头表示可接受的响应内容。与Accept首部类似的还有AcceptCharset、AcceptEncoding、AcceptLanguage等首部,分别表示客户端可接受的字符集、可接受的编码方式和可接受的语言。 值得注意的是,HTTP 1.1为这些首部引入了品质因子q(quality value),用来表示不同版本的可用性。 例如在上文请求头中,Accept属性值中出现了两个品质因子q,服务器会优先选取品质因子值高的对应资源版本作为响应。 2) Host HTTP 1.1添加Host首部来表示服务器的域名以及服务器所监听的端口号(如果所请求的端口为所请求服务的标准端口,则端口号可以省略)。例如图310请求头中的“Host: www.fudan.edu.cn”字段表示客户端请求访问域名为“www.fudan.edu.cn”的服务器的80端口。HTTP 1.0认为每台服务器都绑定一个唯一的IP地址,但目前多个虚拟站点可以共享同一个IP地址。在加入Host首部后,其属性值可以明确指出要访问IP地址上的哪个站点。应当指出的是,请求头中必须包含Host首部,否则服务器会返回一个错误。 3) Range HTTP 1.1在请求头中添加Range首部表示客户端向服务器请求资源的某个部分。例如“Range: bytes=0499”,表示客户端请求实体的前500字节。Range首部的使用避免了服务器向客户端发送其不需要的资源,从而造成带宽浪费。在从Web服务器下载文件时,所使用的断点续传功能就依赖于这个首部的使用。 4) UserAgent UserAgent属性表示客户端的身份标识字符串。通过该字符串使得服务器能够识别客户使用的操作系统及版本、CPU类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等信息。对于浏览器而言,该字符串的标准格式为: 浏览器标识 (操作系统标识; 加密等级标识; 浏览器语言) 渲染引擎标识 版本信息 一个例子如下: User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36 对于爬虫程序而言,该属性的值是可以随便设置的,并不一定要遵守浏览器和格式,但是这种方式增加了服务器识别爬虫的风险。 5) ContentRange 与请求头的Range属性相对应,HTTP 1.1在响应头中添加ContentRange首部表示服务器已响应客户端请求的部分资源。例如“ContentRange: bytes 0499/1024”表示已经响应了实体的前500字节,斜杠后面的数字表示实体的大小。 6) ContentType ContentType首部表示响应体的MIME类型,即响应体是用何种方式编码的。常见的媒体编码格式类型有text/html(HTML格式)、text/plain(纯文本格式)、image/jpeg(jpg图片格式); 以application开头的媒体格式类型有application/json(JSON数据格式)、application/pdf(PDF格式)、application/msword(Word文档格式)。 7) Cookie Cookie是请求报文中可用的属性,也是客户端最重要的请求头属性。Cookie存储了客户端的一些重要信息,例如身份标识、所在地区等,通常是一个文本文件。在向服务器发送URL请求时可以将文件内容读出,附加在HTTP的请求头中,能免去用户输入信息的麻烦。 8) SetCookie SetCookie是响应报文中可用的属性,服务器可以在响应报文中使用该属性将一些信息推送给客户端。客户端收到信息后,通常的做法是生成Cookie文件,将这些内容保存起来。例如以下代码表示服务器发送UserID、Version信息给客户端,希望客户端将它们保存到Cookie文件中。 Set-Cookie: UserID=Wang12; Version=1 9) Connection Connection是请求报文和响应报文中都可用的属性,通过该属性可以允许客户端和服务器指定与请求/响应连接有关的选项,相应的属性值有keepalive、Upgrade。 从前面关于HTTP协议版本技术特性演变的介绍可以看出keepalive是一个很重要的属性,然而 并不是设置了keepalive就意味着可以建立永久连接。在默认情况下,Web服务端设置了keepalive的超时时间,当连接超过指定的时间时服务端就会主动关闭连接。此外,为了提高HTTP响应时间,避免Web服务拥塞,并发连接数 (即同时处于keepalive的连接的数目)也不宜太大。 10) ContentLength ContentLength首部表示响应体的长度,其属性值用八进制字节表示。 11) ContentLanguage ContentLanguage首部表示响应内容所使用的语言。 12) Server Server表示服务器名称。 13) Warning HTTP 1.1在响应头中添加Warning首部来更好地描述错误和警告信息,这些信息通常比原因短语更详细。 14) Referer HTTP Referer是header的一部分,当浏览器向Web服务器发送请求时一般会带上Referer属性值,告诉服务器该请求是从哪个页面链接过来的。例如B页面上有个链接到A,当用户从该链接访问A时,发送给A所在的Web服务器的请求头中的Referer值就是B。 3.4.4HTTP状态码 HTTP状态码(HTTP Status Code)是用来表示Web服务器HTTP响应状态的3位数字代码。通过HTTP状态码可以得知服务器的响应状态,以便更好地处理通信过程中遇到的问题。对于爬虫程序而言,可以通过这个状态码确定页面抓取结果。HTTP状态码由RFC 2616规范定义,并得到RFC 2518、RFC 2817、RFC 2295、RFC 2774、RFC 4918等规范扩展。状态码包含了5种类别,即消息、成功、重定向、请求错误和服务器错误。 状态码由3位数字构成,例如200,表示请求成功。数字中的第一位代表了状态码所属的响应类别,共有五大类状态码,分别以1~5几个数字开头,如表31所示。 表31状态码的类别 状态码类别分 类 描 述 1XX信息状态码表示服务器已经收到请求,需要继续处理。在HTTP 1.0中没有定义1XX状态码,因此除非在某些试验条件下,服务器不要向客户端发送1XX响应 2XX成功状态码表示请求被成功接收并处理 3XX重定向状态码表示需要采取进一步操作才能完成请求。这类状态码用来重定向,对于GET或HEAD请求,服务器响应时会自动将客户端转到新位置 4XX客户端错误状态码表示客户端的请求可能出错,服务器无法处理请求 5XX服务器错误状态码表示服务器在处理请求的过程中内部发生了错误 服务器返回的状态码后常跟有原因短语(例如200 OK),原因短语为状态码提供了文本形式的解释。 状态码的个数很多,被RFC 2616、RFC 2518、RFC 2817等规范定义的状态码有60多个,但实际常见的状态码仅有以下10个,通常用在爬虫程序中。 (1) 成功状态码。 200(OK): 这是最常见的状态码,表示服务器成功处理了请求,同时请求所希望的响应头或实体随着响应返回。 202(Accepted): 表示服务器已接受请求,但尚未处理。 (2) 重定向状态码。 301(Moved Permanently): 表示请求的资源已经永久地移动到新位置,即被分配了新的URL。客户端以后的新请求都应使用新的URL。 304(Not Modified): 表示客户端发送了一个带条件的GET请求且该请求已被允许,而文档的内容并没有改变。在返回的响应报文中不含实体的主体部分。 (3) 客户端错误状态码。 400(Bad Request): 表示请求报文存在语法错误或参数错误,服务器无法理解。 401(Unauthorized): 表示当前请求要求客户端进行身份认证或是身份认证失败。对于需要登录的网页,服务器可能返回此响应。 403(Forbidden): 表示服务器已经理解请求,但是拒绝执行。拒绝执行可能是由于客户端无访问权限等原因,但服务器无须给出拒绝执行的理由。 404(Not Found): 表示请求失败,在服务器上无法找到请求的资源。 (4) 服务器错误状态码。 500(Internal Server Error): 表示服务器执行请求时发生错误,无法完成请求。当服务器端的源代码出现错误时会返回这个状态码。 503(Server Unavailable): 表示服务器超负载或正停机维护,无法处理请求。这个状态通常是临时的,将在一段时间后恢复。 3.4.5HTTPS HTTPS(Hypertext Transfer Protocol Secure,超文本传输安全协议)是一种通过计算机网络进行安全通信的传输协议,简单来说,HTTPS是HTTP协议的安全版本。HTTP报文使用明文发送,传输的信息很容易被监听和篡改; HTTPS是使用SSL/TLS加密的HTTP协议,可以保护传输数据的隐私和完整性,同时实现服务器的身份验证。 SSL(Secure Sockets Layer,安全套接层)是介于HTTP与TCP之间的安全协议,SSL在传输层同时使用对称加密以及非对称加密对网络连接进行加密。其中,对称加密算法的加密与解密使用同一个密钥; 非对称加密算法的加密与解密使用不同的两个密钥,即公开密钥(public key,简称公钥)和私有密钥(private key,简称私钥)。非对称加密与对称加密相比安全性更高,但是加密与解密花费的时间长、速度慢。因此,在准备建立连接时,SSL使用服务器的证书(公钥)将对称密钥非对称加密,保证对称密钥的安全; 在连接建立后,SSL对数据量较大的传输内容使用对称加密,提高加密效率。 传输层安全协议(Transport Layer Security Protocol,TLS)是SSL 3.0的后续版本,与SSL的内容大致相同,因此很多文章将TLS与SSL并列称呼,即SSL/TLS。 HTTPS相当于在HTTP的基础上使用SSL/TLS对传输的数据进行加密,因此HTTPS与HTTP交互最大的区别在于,使用HTTPS传输数据之前需要客户端与服务器进行一次SSL握手,在握手过程中将确立双方加密传输数据的密码信息。如图312所示,下面主要介绍SSL握手中的单向认证过程,即客户端校验服务器的证书合法性。 图312HTTPS交互过程 (1) 客户端的浏览器发送客户端SSL协议的版本号、加密算法的种类、产生的随机数以及其他在SSL协议中需要用到的信息。 (2) 服务器向客户端返回SSL协议的版本号、加密算法的种类、随机数以及其他相关信息,同时服务器还将向客户端传送自己的证书。证书用于身份验证,其中包含用于非对称加密的公共密钥。 (3) 客户端用服务器传过来的证书进行服务器信息校验。服务器信息校验的内容包括证书链是否可靠、证书是否过期、证书域名是否与当前的访问域名匹配等。如果服务器信息校验没有通过,结束本次通信,否则继续进行第(4)步。 (4) 客户端随机生成一个用于后续通信的对称密钥,然后使用服务器在第(2)步发来的公共密钥对其加密,之后将加密的对称密钥发送给服务器。 (5) 服务器使用私有密钥解密客户端发来的信息,得到用于后续通信的对称密钥。 (6) 客户端向服务器端发送信息,信息中指明协商后续通信要使用的对称密钥完成,后面的通信都要使用第(5)步得出的对称密钥进行加密,同时通知服务器握手过程结束。 (7) 服务器也向客户端发送协商后续通信要使用的对称密钥完成,握手过程结束。 之后SSL的握手结束,客户和服务器开始使用相同的对称密钥对要传输的数据进行加密,同时进行通信完整性的检验。 3.5状态保持技术 当使用浏览器访问Web服务器上的页面时,浏览器首先会建立与Web服务器的HTTP连接,之后浏览器在这个连接上发送URL,接收服务器返回的信息,并显示在浏览器上。如果进行连接复用或持久化,后续的URL请求和响应信息接收都可以在这个连接上进行,这些请求之间是相互独立的。 如果前后两次URL请求之间需要共享某些数据,例如在第一个页面进行了用户登录,第二个页面的访问就需要以该用户身份进行。更简单地讲,一个客户端访问服务器时,可能会在这个Web服务器上的多个页面之间不断刷新、反复连接同一个页面或者向一个页面提交信息。在这种情况下,不同页面之间或同一个页面的不同次访问之间需要保持某种状态,实现这种需求的技术就是状态保持技术。 由于HTTP协议本身是无状态的,客户端向服务器发送一个request,然后服务器返回一个response,不同URL之间的状态无法共享,即状态无法保持。在一个通信系统中要实现状态保持,只能从客户端和服务端两个角度来设计, 相应地,这两种状态保持技术就是Cookie和Session。 3.5.1Cookie Cookie是由服务端生成,并在客户端进行保存和读取的一种信息,Cookie通常以文件形式保存在用户端。查看Cookie的方法 随着浏览器的不同而不同,图313、图314分别是在Chrome和IE中的查看方法。 图313在Chrome中查看Cookie的方法 图314在IE中查看Cookie的方法 对于IE浏览器来说,Cookie保存在本地计算机的缓存目录中,其默认位置在管理员目录下,例如“C:\Users\Administrator\AppData\Local\Microsoft\Windows\Temporary Internet Files”。进入该目录中可以看到很多Cookie文件,如图315 所示。 图315Cookie文件示例 从图中可以看出,Cookie文件名称的形式为Cookie:$$$$@XXXX,其中$$$$表示系统用户,XXXX表示生成Cookie的网站。 每个Cookie有4个时间,即过期时间、上次修改时间、上次访问时间和上次检查时间。 在文本文件中打开Cookie文件,可以发现每个文件中包含一个或多个Cookie记录,而每个记录中包含了名字、值、过期时间、路径和域,具体解释如表32所示。 表32Cookie文件内容解释 Cookie文件中的一个记录对应行的解释取 值 样 例 nameCookie变量名uid valueCookie变量值abcxyz001 domain+pathCookie变量所属的域、路径,即作用范围mail.fudan.edu.cn/ option可选标志1600 a过期时间(FILETIME格式)的高位整数1638219776 b过期时间(FILETIME格式)的低位整数36669619 c创建时间(FILETIME格式)的高位整数1256217104 d创建时间(FILETIME格式)的低位整数30651615 *Cookie记录分隔符 在表中名字(name)和值(value)并没有特殊的命名规定,也没有写法上的限定。由于Cookie是在服务端生成,最终由浏览器 进行解析,所以这些名字和值一般与页面的某些变量有关。 域(domain)是指Cookie变量所属的域,也就是该Cookie的有效域范围。路径是接在域后面的URL路径,最简单的路径是/,也可以是/image等形式。路径与域合在一起就构成了Cookie的作用范围,表示Cookie变量在该范围内的网页都有效,不管用户访问该目录中的哪个网页,浏览器都会将该Cookie信息附在网页头部中,并发送给服务端。 如果设置了过期时间,浏览器会把Cookie保存到硬盘上,当关闭后再次打开浏览器时,这些Cookie仍然有效直到超过设定的过期时间。如果没有设置过期时间,则表示这个Cookie的生命期为浏览器会话期,只要关闭浏览器窗口,Cookie就消失了。这种生命期为浏览器会话期的Cookie被称为会话Cookie。会话Cookie一般不存储在硬盘上,而是保存在内存里。 这里举一个例子,在一个提供页面登录的Web页面(http://mail.fudan.edu.cn/)中 勾选了“记住用户名”选项,希望浏览器记住用户名(如图316所示),之后随便输入一个用户名,例如abcxyz001, 单击“登录”按钮,再重新加载该页面,就会发现浏览器自动填充了用户名。 这时查看mail.fudan.edu.cn的Cookie文件就会发现,文件中的一个记录如图317所示,可以看出名字和值分别为uid、abcxyz001。uid实际上就是图316中用户名输入框的名字。 图316某Web页面 图317Cookie文件中的一个记录 在了解了Cookie文件的内容之后,需要了解Cookie的创建和使用方法。Cookie中记录的内容是在服务器端生成的,然后通过HTTP headers从服务器端发送到浏览器上。 浏览器在处理用户输入的URL时,根据其中的域名寻找是否有相应的Cookie文件,如果有,则进一步检查其中的作用范围。当作用范围大于等于URL指向的位置时,浏览器会将该Cookie中的内容读出,附在请求资源的HTTP请求头上并发送给服务器。 具体的创建和使用方式与Web服务的框架和支持的语言有一定关系,但基本原理是一样的。这里以上面的登录处理为例,这是一个JSP页面,假如为Login.jsp,单击“登录”按钮之后,将输入的用户名、密码提交给action="results.jsp"进行处理。那么 在results.jsp中,下面的脚本将用户输入的用户名作为Cookie的值(value),其对应的名字(name)为“username”。最后通过response让浏览器端生成一个Cookie文件。 String username = request.getParameter("username"); Cookie cookie1 = new Cookie("username",username); //创建Cookie cookie1.setMaxAge(3600); //设置过期时间,以秒为单位 cookie1.setPath("/"); //设置路径 response.addCookie(cookie1);//发送到浏览器端执行创建动作 在下面的代码段中,服务器获得浏览器发送的Cookie内容,并从中取出用户名。这段代码可以嵌入到自动输入用户名的页面中。 Cookie cookies[]=request.getCookies(); Cookie sCookie=cookies[1]; String username=sCookie.getValue(); 接着就可以按照下面的方式将username变量赋值给输入框,然后发送给浏览器,这样在浏览器上就能看到填充的用户名了。 <input type="text" name="username" value =<%=username%> size="44"> 视频讲解 3.5.2Session 仅使用Cookie来保持状态存在一定的问题,主要表现在以下几个方面: (1) Cookie虽然可以灵活地增加名字(name)和值(value),但是每个域名的Cookie数量、Cookie文件大小是受限的,具体数值取决于不同浏览器。例如Firefox将每个域名的Cookie限制为最多50个,每个文件最多4KB。因此,在一些需要在客户端和Web服务器之间进行较多数据交换的应用中,使用Cookie就不合适。 (2) Cookie存在一定的安全风险,Cookie信息可以很容易被截获,如果是明文,则可能造成信息泄露。但不管是明文还是密文,都可以直接被用来伪造HTTP请求,即Cookie欺骗,冒充受害人的身份登录网站。 Session是另一种常见的在客户端与服务器之间保持状态的机制,在一定程度上解决或缓解了上述问题,准确理解其技术原理有利于设计更好的动态爬虫。 Session可以看作是Web服务器上的一个内存块,能够将原本保存在Cookie中的用户信息存储在该内存块中,而客户端和服务器之间依靠一个全局唯一标识“Session_id”来访问Session中的用户数据,这样只需要在Cookie中保存Session_id就可以实现不同页面之间的数据共享。可见在Session机制下除了Session_id以外,其他用户信息并不保存到Cookie文件中,这解决了上述两个问题。 虽然Session_id也可能会像Cookie内容一样被截获,但通常Session_id是加密存储的。对于安全性保障更有效的机制是它的动态性,即Session是在调用HttpServletRequest.getSession(true)这样的语句时才被创建,而在符合下面3个条件之一时终止: (1) 程序调用HttpSession.invalidate()。 (2) 服务器关闭或服务停止。 (3) Session超时,即在一定的连续时间内服务器没有收到该Session所对应客户端的请求,并且这个时间超过了服务器设置的Session超时的最大时间。这个最大时长一般是30分钟,在服务器上可配置。 因此只要Session在内存中的存活时间不是太长,当攻击者截获到某个Session_id时其对应的内存Session可能已经销毁了, 故也就无法获得用户数据。 根据以上描述,可以画出Session、Cookie、服务器和客户端(浏览器、爬虫)之间的关系,如图318所示。 图318Session、Cookie、服务器和客户端的关系图 思考题 1. Web服务器及应用架构与网络爬虫之间是什么关系? 2. 学习使用Tomcat等Web服务器软件制作页面,并在浏览器中浏览。 3. 浏览器需要遵守Robots协议吗? Robots协议中主要规定了哪些方面的内容? 4. 不同版本的HTTP协议存在的主要区别是什么? 5. 学习使用浏览器的开发者工具查看HTTP请求报文、响应报文、状态码和Cookie。 6. 谈谈Cookie的作用。