• 加强对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 项,交由服务器判断页面是否被更新过。

    参见:

      1. All About Search Indexing Robots and Spiders http://www.searchtools.com/robots/
      2. Stealth bots. How to detect them? http://www.webmasterworld.com/forum11/2562.htm
      3. 超文本传输协议 -- HTTP/1.0 (Hyptertext Transfer Protocol - HTTP/1.0)http://www.delphidevelopers.com/technical/RFC/RFCs/RFC1945.txt
  • 相关阅读:
    【python27】猜随机数的小游戏
    【Python】【unittest】unittest测试框架中setup,teardown与setupclass,teardownclass的区别
    【Android自动化】unittest测试框架关于用例执行的几种方法
    【Android自动化】在使用uiautomator框架自动化时,往往有时再运行脚本时发现xxx实例属性不被允许
    史前第一篇,关于 类 的初次学习
    Emboss滤波器实现及应用
    Laplacian滤波器实现并用于图像锐化
    Prewitt 滤波器对图像进行边缘检测
    使用Sobel算子检测图像的水平特征和垂直特征
    差分滤波器的介绍及用于图像特征检测
  • 原文地址:https://www.cnblogs.com/xuan52rock/p/4495233.html
Copyright © 2020-2023  润新知