http 协议学习
ContentType
指定响应的 HTTP 内容类型,缺省值为text/HTML。
通常被格式化为类型/子类型,其中类型是常规内容范畴而子类为特定内容类型。
".*"="application/octet-stream"
".biz"="text/xml"
".dtd"="text/xml"
".htm"="text/html"
".html"="text/html"
如:xmlHttpRequest.setRequestHeader("content-type","application/x-www-form-urlencoded; charset=utf-8")
HTTP1.1那里体现出来长连接了?
http://baike.baidu.com/view/9472.htm
HTTP 请求和 HTTP 响应都使用头发送有关 HTTP 消息的信息。
HTTP/1.1协议
HTTP 定义了与服务器交互的不同方法,最常用的有几种:
GET: 请求指定的页面信息,并返回实体主体。
HEAD:只请求页面的首部。
POST:POST和GET之间的区别并不总是那么严格,也存在一些共性。
协议格式
HTTP的头域包括通用头,请求头,响应头和实体头四个部分。
每个头域由一个域名,冒号(:)和域值三部分组成。域名是大小写无关的,
域值前可以添加任何数量的空格符,头域可以被扩展为多行,在每行开始处,使用至少一个空格或制表符。
1,通用头域包含Cache-Control、 Connection、Date、Pragma、Transfer-Encoding、Upgrade、Via
Cache-Control指定请求和响应遵循的缓存机制。在请求消息或响应消息中设置 Cache-Control并不会修改另一个消息处理过程中的缓存处理过程。
请求时的缓存指令包括no-cache、no-store、max-age、 max-stale、min-fresh、only-if-cached,
响应消息中的指令包括public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age。
Public指示响应可被任何缓存区缓存。
no-cache指示请求或响应消息不能缓存
no-store在请求消息中发送将使得请求和响应消息都不使用缓存。
max-age客户机可以接收生存期不大于指定时间(以秒为单位)的响应。
min-fresh指示客户机可以接收响应时间小于当前时间加上指定时间的响应。//响应时间,当前时间皆为一个时间点
max-stale客户机可以接收超出超时期指定值之内的响应消息。
Pragma:指定“no-cache”值表示服务器必须返回一个刷新后的文档,即使它是代理服务器而且已经有了页面的本地拷贝。
2,请求头
典型的Post请求
POST /cgi-bin/Login.cgi HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-
powerpoint, application/vnd.ms-excel, application/msword, */*
Referer: http://localhost//login.html
Accept-Language: zh-cn
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)
Host: localhost:8080
Content-Length: 70
Connection: Keep-Alive
Usernme=aaaa&passwd=bbbb&Submit=+%E7%A1%AE%E5%AE%9A%E5%82%A8%E5%80%BC+
/**注释
*Accept 可接收的文件格式的mime类型
*Referer 引用链接,通常是你上一次点击的url位置。允许服务器生成回退链表
*Accept-Language 浏览器用来展示返回信息所优先选择的语言。
*Content-type用于规定下层数据的媒体类型,application/x-www-form-urlencoded表示是个form表单的url的百分号编码
*Accept-Encoding 可接受的数据压缩格式
*Content-Length body的内容长度
*Connection: Keep-Alive.. http连接状态,
*Host指定请求资源的Intenet主机和端口号,必须表示请求url的原始服务器或网关的位置。*
*Range头域可以请求“实体(如html源代码)的一个或者多个子范围”。例如,
*表示头500个字节:bytes=0-499
*表示第二个500字节:bytes=500-999
*表示最后500个字节:bytes=-500
*表示500字节以后的范围:bytes=500-
*第一个和最后一个字节:bytes=0-0,-1
*同时指定几个范围:bytes=500-600,601-999
*但是服务器可以忽略此请求头,
*User-Agent 浏览器,OS等信息。getHead("User-Agent");
*/
3、响应消息//SP空格
HTTP-Version表示支持的HTTP版本,例如为HTTP/1.1。
1xx:信息响应类,表示接收到请求并且继续处理
2xx:处理成功响应类,表示动作被成功接收、理解和接受
3xx:重定向响应类,为了完成指定的动作,必须接受进一步处理
4xx:客户端错误,客户请求包含语法错误或者是不能正确执行//如404是指定的请求不错在,403
5xx:服务端错误,服务器不能正确执行一个正确的请求
响应头包含Age、Location、Proxy-Authenticate、Public、Retry-After、Server、Vary、Warning、WWW-Authenticate。
典型的响应消息:
HTTP/1.0 200 OK
Date:Mon,31Dec200104:25:57GMT
Server:Apache/1.3.14(Unix)
Content-type:text/html
Last-modified:Tue,17Apr200106:46:28GMT
Etag:"a030f020ac7c01:1e9f"
Content-length:39725426
Content-range:bytes554554-40279979/40279980
Location响应头用于重定向接收者到一个新URI地址。
Server响应头包含“处理请求的原始服务器的软件信息”。此域能包含多个产品标识和注释,产品标识一般按照重要性排序。
4、实体信息
请求消息和响应消息都可以包含实体信息,实体信息一般由实体头域和实体组成。
实体头域包含关于实体的原信息,实体头包括Allow、Content-Base、Content-Encoding、Content-Language、Content-Length、
Content-Location、Content-MD5、Content-Range、Content-Type、Etag、Expires、Last-Modified、extension-header。extension-header
实体可以是一个经过编码的字节流,它的编码方式由Content-Encoding或Content-Type定义,它的长度由Content-Length或Content-Range定义。
Content-Range指定整个实体中的插入位置,他也指示了整个实体的长度。
Content-Range:bytes-unit SP first-byte-pos - last-byte-pos/entity-legth
5、补充
Upgrade "SHTTP/1.3"
Via "HTTP/1.1 Proxy1, HTTP/1.1 Proxy2"
Cache-control private
Set-Cookie ASPSESSIONIDQQGGGNCG=LKLDFFKCINFLDMFHCBCBMFLJ; path=/
6、GET/POST:
GET:请求幂等(字面意思是请求任意次返回同样的结果,请求本身不会改变服务器数据和状态)
POST:当请求会改变服务器数据或状态时(更新数据,上传文件)
重复访问使用GET方法请求的页面,浏览器会使用缓存处理后续请求。
form的enctype属性为编码方式
两种:application/x-www-form-urlencoded(默认)和 multipart/form-data。
GET,浏览器用x-www-form-urlencoded的编码方式把form数据转换成字串(name1=value1&name2=value2...),
再append到url后面,数据严格限制为ASCII码
POST,浏览器content type编码字符集,把form数据封装到http body中,然后发送到server。
7、MIME意为多目Internet邮件扩展,最初为了在发送电子邮件时附加多媒体数据,现在已被HTTP协议支持
MIME格式:大类/小类
超文本标记语言文本.html text/html
普通文本.txt text/plain
GIF图形.gif image/gif
JPEG图形.jpeg image/jpeg
ZIP文件.zip - application/zip.
以x-开头的表明这个类别还没有成为标准类型
MIME类型与文档的后缀相关,服务器使用文档的后缀来区分不同文件的MIME类型,因此服务器中必须定义文档后缀和MIME类型之间的对应关系。
而客户程序从服务器上接收数据的时候,它只是从服务器接受数据流,并不了解文档的名字,因此服务器必须使用附加信息来告诉客户程序数据的MIME类型。
服务器在发送真正的数据之前,就要先发送标志数据的MIME类型的信息,这个信息使用Content-type关键字进行定义。如:Content-type: text/html
8、爬虫User-Agent
在使用浏览器上网的时候,客户的浏览器在Http请求的Header中会带上User-Agent.
IE的User-Agent. 一般为: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; POTU(RR:27091922:0:); .NET CLR 1.1.4322; .NET CLR 2.0.50727).
FF的User-Agent. 一般为: Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11.
User-Agent可以方便的被Javascript操作(navigator.userAgent)。但是User-Agent在Javascript中是一个只读属性。
服务器端使用HttpRequest.UserAgent $_SERVER["HTTP_USER_AGENT"] 取得User-Agent来确定客户使用的是什么浏览器。
流氓爬虫,伪装自己。今天抓取自己学校的物理学院的网址,竟然发现
java.io.IOException: Server returned HTTP response code: 500 for URL: http://physics.whu.edu.cn/show.asp?id=278
java.io.IOException: Server returned HTTP response code: 403 for URL
但是自己却可以用浏览器访问,发现可能是服务器对我们这种java程序屏蔽了。
因为服务器的安全设置不接受Java程序作为客户端访问,解决方案是设置客户端的User Agent
url = new URL("http://physics.whu.edu.cn/show.asp?id=278");
HttpURLConnection connection = (HttpURLConnection) url.
openConnection();
connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
这样就可以访问了。
几乎每个大型门户网站都有自己的搜索引擎,搜狐,腾讯,网易
网易有道搜索曾经在一个上午的时间就访问了JavaEye网站60多万次请求,把网站访问拖得很慢,被我们立刻封杀。
雅虎爬虫的爬行也十分弱智,经常循环爬取,爬行频率非常高,
最可怕的还是奇虎的爬虫,常并发上百个请求同时爬取,web servr上面堵塞了几百个来自奇虎爬虫的请求。
百度的爬虫早期也是如此,现在已经斯文多了
例如lighttpd可以这样配置:
$HTTP["url"] =~ "^/topics/download/" { evasive.max-conns-per-ip = 2 }
限定每IP只能并发一个线程下载。
主流的网站流量统计系统不外乎两种策略:
一种策略是在网页里面嵌入一段js,这段js会向特定的统计服务器发送请求的方式记录访问量;
另一种策略是直接分析服务器日志,来统计网站访问量。
在理想的情况下,嵌入js的方式统计的网站流量应该高于分析服务器日志,这是因为用户浏览器会有缓存,不一定每次真实用户访问都会触发服务器的处理。
但实际情况是,分析服务器日志得到的网站访问量远远高于嵌入js方式,极端情况下,甚至要高出10倍以上。
爬虫为了避免被网站以识别User-Agent的方式封杀,就修改了自己的User-Agent信息,通常伪装成WindowsXP上的IE6浏览器,也有伪装成Firefox浏览器的。这种情况下awstats无法有效的识别了,所以awstats的统计数据会虚高。不过说句公道话,这也怪不了awstats,只怪爬虫太狡猾,不但awstats无法有效识别,就算我们肉眼去查看日志,也往往无法有效识别。
JavaEye网站就开发了自己的网站流量统计系统,采用在页面里面嵌入js的方式来实现网站流量统计。因此我们可以精确的掌握登录用户和非登录用户的比例,不同的访问偏好,JavaEye每个频道精确的流量和比例,真实的用户数量和分布等GA无法提供的有价值的信息。
只有用户使用浏览器访问页面的时候才会执行js,而爬虫并不会执行页面里面的js
这仅仅需要一条shell命令:
grep Processing production.log | awk '{print $4}' | awk -F'.' '{print $1"."$2"."$3".0"}' | sort | uniq -c | sort -r -n | head -n 200 > stat_ip.log
例如JavaEye现在的白名单(放行的名单)
61.135.163.0 百度
61.135.216.0 有道
65.55.106.0 微软
65.55.207.0 微软
65.55.211.0 微软
66.249.66.0 Google
72.14.199.0 Google
121.0.29.0 阿里巴巴
123.125.66.0 百度
......
新的爬虫的爬取方式,就是不用程序去爬取,而是编程控制一个真正的浏览器内核去爬取网站,由于浏览器内核可以真正执行js,所以会被识别为真实用户访问,从而避开网站的检查机制。这种爬虫是最难以甄别的爬虫,如果精心编写,甚至可以欺骗Google的服务器。由于Safari的webkit浏览器内核和Firefox的Gecko浏览器内核都是开源的,因此一个水平比较高的程序员自己动手编写程序驱动一个真实的浏览器内核作为爬虫并不是非常困难的事情。
嵌入式js的缺点是,不能防止真正用浏览器爬行的爬虫。
嗯,这个我们做过试验,如果去掉浏览器的Layout算法和/或GUI渲染(当需要布局信息时)的部分,数据抓取速度还是很快的。
真正的入手点,还是应该从cookie和用户行为上入手。
一般用户是不会有规律的一页接一页看的。