加强对HEAD 请求的处理(转贴)
最近发现有些搜索引擎爬虫在抓取数据的时候,先是通过一个HEAD 请求获取response的header 信息,然后再通过GET 请求获取response 的body信息(即页面的内容)——先发送HEAD 请求是为了获得页面的更新时间(即response header 中的Last-Modified 域),用于判断自从上一次该页面被收入索引库以后有没有被更新过,如果判断页面没有被更新过就忽略该页面,否则就再用GET 方法获取一次最新的内容并更新到索引库中。
在页面更新频率比较低或者缓存设置的时间比较长的情况下,这样做可以避免在网络上传送体积比较大的body 域、降低网络消耗,而且还也可以缩短索引的更新时间。但在页面更新频率比较高,或者页面缓存时间比较短的情况下效果却是相反的:
如果被抓取的页面在缓存中,情况会稍微好一些,缓存服务器(如安装了expires_module 的Apache)在接收到HEAD 请求时会把缓存后的response 的header 域返回给爬虫,在接下来的GET 请求时再把缓存后的整个response (包括header 域和body 域)都返回给爬虫;
如果被抓取的页面不在缓存中,而程序中又缺少专门针对HEAD 请求的处理方法,那么就会导致该页面被生成两次——在处理HEAD请求的时候,因为没有专门的方法,于是一般用于处理GET 请求的方法就会被执行,程序执行后生成了完整的response,缓存服务器接收到该response,但只会把它的header 信息返回给爬虫,并不会对该response 进行缓存;在处理接下来的GET 请求的时候,因为没有缓存所以程序还要再生成一遍完整的response,并由缓存服务器转交给爬虫,这时缓存服务器才会把response 缓存起来。这样程序就被执行了两次,第一次执行很大程序上来说是一种浪费。
解决问题的一种方法就是在程序中加入对HEAD 请求的处理。在处理HEAD 请求的时候一般只要设置response header 中Content-Type 和Content-Length 就可以了,如: 在servlet 可以通过重载doHead(HttpServletRequest request, HttpServletResponse response) 的方法实现:
public void doHead(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// Set the content length and type
resp.setContentType("text/html; charset=GB2312");
resp.setContentLength(30000);
}
而在jsp 中则可以仿照下面的方式:
<%
/* handle the HEAD request */
if(request.getMethod().equals("HEAD")) {
response.setDateHeader("Last-Modified", System.currentTimeMillis()); /* 设置Last-Modified */
response.setContentType("text/html; charset=GB2312"); /* 设置Content-Type */
response.setContentLength(30000); /* 设置 Content-Length */
return;
}
%>
下面是log 中的一个片断,显示了IP为202.108.1.4 的某个用户/爬虫/代理服务器(奇怪的UserAgent 项)的访问日志:
202.108.1.4 - - [06/Mar/2005:11:21:03 +0800] "HEAD /2001-03-07/28456.htm HTTP/1.1" 200 0 "-" "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)"
202.108.1.4 - - [06/Mar/2005:11:21:03 +0800] "GET /2001-03-07/28456.htm HTTP/1.1" 200 32182 "-" "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)"
202.108.1.4 - - [06/Mar/2005:11:21:09 +0800] "HEAD /2003-06-26/169417.htm HTTP/1.1" 200 0 "-" "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)"
202.108.1.4 - - [06/Mar/2005:11:21:09 +0800] "GET /2003-06-26/169417.htm HTTP/1.1" 200 34693 "-" "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)"
202.108.1.4 - - [06/Mar/2005:11:21:11 +0800] "HEAD /2005-1-5/361944.htm HTTP/1.1" 200 0 "-" "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)"
202.108.1.4 - - [06/Mar/2005:11:21:11 +0800] "GET /2005-1-5/361944.htm HTTP/1.1" 200 36761 "-" "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)"
另,目前只有较少的老式搜索引擎爬虫在采用这种方式抓取页面,如AOL 的爬虫,而大部分搜索引擎爬虫都在采用另外一种方式:即在GET 请求的header 中加入If-Modified-Since 项,交由服务器判断页面是否被更新过。
参见:
- All About Search Indexing Robots and Spiders http://www.searchtools.com/robots/
- Stealth bots. How to detect them? http://www.webmasterworld.com/forum11/2562.htm
- 超文本传输协议 -- HTTP/1.0 (Hyptertext Transfer Protocol - HTTP/1.0)http://www.delphidevelopers.com/technical/RFC/RFCs/RFC1945.txt
加强对HEAD 请求的处理(转贴)的更多相关文章
- Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求
上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...
- Android请求网络共通类——Hi_博客 Android App 开发笔记
今天 ,来分享一下 ,一个博客App的开发过程,以前也没开发过这种类型App 的经验,求大神们轻点喷. 首先我们要创建一个Andriod 项目 因为要从网络请求数据所以我们先来一个请求网络的共通类. ...
- 重温Http协议--请求报文和响应报文
http协议是位于应用层的协议,我们在日常浏览网页比如在导航网站请求百度首页的时候,会先通过http协议把请求做一个类似于编码的工作,发送给百度的服务器,然后在百度服务器响应请求时把相应的内容再通过h ...
- Taurus.MVC 2.2 开源发布:WebAPI 功能增强(请求跨域及Json转换)
背景: 1:有用户反馈了关于跨域请求的问题. 2:有用户反馈了参数获取的问题. 3:JsonHelper的增强. 在综合上面的条件下,有了2.2版本的更新,也因此写了此文. 开源地址: https:/ ...
- nodejs之get/post请求的几种方式
最近一段时间在学习前端向服务器发送数据和请求数据,下面总结了一下向服务器发送请求用get和post的几种不同请求方式: 1.用form表单的方法:(1)get方法 前端代码: <form act ...
- ajax异步请求
做前端开发的朋友对于ajax异步更新一定印象深刻,作为刚入坑的小白,今天就和大家一起聊聊关于ajax异步请求的那点事.既然是ajax就少不了jQuery的知识,推荐大家访问www.w3school.c ...
- C# MVC 5 - 生命周期(应用程序生命周期&请求生命周期)
本文是根据网上的文章总结的. 1.介绍 本文讨论ASP.Net MVC框架MVC的请求生命周期. MVC有两个生命周期,一为应用程序生命周期,二为请求生命周期. 2.应用程序生命周期 应用程序生命周期 ...
- nodejs进阶(5)—接收请求参数
1. get请求参数接收 我们简单举一个需要接收参数的例子 如果有个查找功能,查找关键词需要从url里接收,http://localhost:8000/search?keyword=地球.通过前面的进 ...
- 无法向会话状态服务器发出会话状态请求。请确保 ASP.NET State Service (ASP.NET 状态服务)已启动,并且客户端端口与服务器端口相同。如果服务器位于远程计算机上,请检查。。。
异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 无法向会话状态服务器发出会话状态请求.请确保 ASP.NET State Ser ...
- [转]利用URLConnection来发送POST和GET请求
URL的openConnection()方法将返回一个URLConnection对象,该对象表示应用程序和 URL 之间的通信链接.程序可以通过URLConnection实例向该URL发送请求.读取U ...
随机推荐
- 【Spring】2、BeanFactory 和FactoryBean的区别
转自:http://chenzehe.iteye.com/blog/1481476 1. BeanFactory BeanFactory定义了 IOC 容器的最基本形式,并提供了 IOC 容器应遵守的 ...
- 聊聊Java内存模型
一.Java内存模型 硬件处理 电脑硬件,我们知道有用于计算的cpu.辅助运算的内存.以及硬盘还有进行数据传输的数据总线.在程序执行中很多都是内存计算,cpu为了更快的进行计算会有高速缓存,最后同步至 ...
- Java Service Wrapper--来自官网文件
-----------------------------------------------------------------------------Java Service Wrapper Pr ...
- css优化,提高性能
CSS 优化主要是四个方面: 加载性能比如不要用 @import 等等,@import会影响css文件的加载速度,考虑加载性能时,主要是从减少文件体积.减少阻塞加载.提高并发方面入手,任何 hint ...
- 设计模式-生成器(Builder)
一.概念 将一个复杂对像的构建与它的表示分离,使得同样的构建过程创建不同的表示,又叫建造模式. 生成器模式的重心在于分离构建算法和具体的构造实现,从而使得构建算法可以重用.采用不同的构建实现,产生不 ...
- 【 js 基础 】【读书笔记】关于this
this 关键字是 Javascript 中很特别的一个关键字,被自动定义在所有函数的作用域中.this提供了一种更优雅的方式隐式“传递”一个对象的引用.今天就来说说 this 的指向问题. this ...
- imanager一些常用方法汇总
一.求和函数(根据键值数组求键值的总和) function sum(arr){ //arr是传入的值数组,格式如["张三","李四","王五" ...
- 微信小程序 发现之旅(二)—— 自定义组件
组件化的项目开发中,组件应当划分为三个层次:组件.模块.页面 微信小程序已经为开发者封装好了基础组件,页面文件(pages)也有了详细的规定 而模块就需要自行开发,并且要和页面文件区分开,这就涉及到自 ...
- BZOJ1802: [Ahoi2009]checker(性质分析 dp)
题意 题目链接 Sol 一个不太容易发现但是又很显然的性质: 如果有两个相邻的红格子,那么第一问答案为0, 第二问可以推 否则第一问答案为偶数格子上的白格子数,第二问答案为偶数格子上的红格子数 #in ...
- SQLServer 学习笔记之超详细基础SQL语句 Part 10
Sqlserver 学习笔记 by:授客 QQ:1033553122 -----------------------接Part 9------------------- 删除约束的语法 ALTER T ...