用python监控节点到源站的http响应时间,简单的ping不能解决问题,可以考虑使用python pycurl模块。
python pycurl模块支持的协议:
supporting FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE and LDAP. libcurl supports HTTPS certificates, HTTP POST, HTTP PUT, FTP uploading, kerberos, HTTP form based upload, proxies, cookies, user+password authentication, file transfer resume, http proxy tunneling and more!
本文例子只需要http一个,相对urlib来说,这个库可能更快些。
例子,对某一个给定的url进行检查,并打印出http相应码,响应大小,建立连接时间,准备传输时间,传输第一个字节时间,完成时间。
运行结果:
pycurl响应信息:
(参考: http://curl.haxx.se/libcurl/c/curl_easy_getinfo.html )
pycurl.NAMELOOKUP_TIME 域名解析时间
pycurl.CONNECT_TIME 远程服务器连接时间
pycurl.PRETRANSFER_TIME 连接上后到开始传输时的时间
pycurl.STARTTRANSFER_TIME 接收到第一个字节的时间
pycurl.TOTAL_TIME 上一请求总的时间
pycurl.REDIRECT_TIME 如果存在转向的话,花费的时间
pycurl.EFFECTIVE_URL
pycurl.HTTP_CODE HTTP 响应代码
pycurl.REDIRECT_COUNT 重定向的次数
pycurl.SIZE_UPLOAD 上传的数据大小
pycurl.SIZE_DOWNLOAD 下载的数据大小
pycurl.SPEED_UPLOAD 上传速度
pycurl.HEADER_SIZE 头部大小
pycurl.REQUEST_SIZE 请求大小
pycurl.CONTENT_LENGTH_DOWNLOAD 下载内容长度
pycurl.CONTENT_LENGTH_UPLOAD 上传内容长度
pycurl.CONTENT_TYPE 内容的类型
pycurl.RESPONSE_CODE 响应代码
pycurl.SPEED_DOWNLOAD 下载速度
pycurl.SSL_VERIFYRESULT
pycurl.INFO_FILETIME 文件的时间信息
pycurl.HTTP_CONNECTCODE HTTP 连接代码
pycurl.HTTPAUTH_AVAIL
pycurl.PROXYAUTH_AVAIL
pycurl.OS_ERRNO
pycurl.NUM_CONNECTS
pycurl.SSL_ENGINES
pycurl.INFO_COOKIELIST
pycurl.LASTSOCKET
pycurl.FTP_ENTRY_PATH
之前同事用ruby实现的一段代码:
#!/usr/bin/env ruby
require 'rubygems'
require 'net/http'
urls = ["http://jb200.com"]
.times do
urls.each do |url|
start_at = Time.now
Net::HTTP.get URI.parse(url)
end_at = Time.now
diff = end_at - start_at
if diff <</span> . then
color_code =
elsif diff > . then
color_code =
else
color_code =
end
puts "#{url}n time: 33[#{color_code}m#{diff} 33[0m seconds"
end
end
改成python代码,考虑脚本的灵活性准备增加两个参数,第一个是请求测试次数,第二个是请求测试的 URL,而 python 默认提供了argparse 库,可以很方便的生成 --help 的帮助和解析传递的参数:
#!/usr/bin/env python
import urllib2
import time
import sys
import argparse
def benchmark(url, count):
for i in range(count):
s = time.time()
r = urllib2.urlopen(urllib2.Request(url))
e = time.time()
diff = e - s
if diff <</span> 0.3:
color_code =
elif diff > 0.8:
color_code =
else:
color_code =
print '# %d' % (i + )
print 'tStauts: %s' % r.getcode()
print 'tTime: 33[%dm%f 33[0m second(s)' % (color_code, diff)
def main(argv):
parser = argparse.ArgumentParser(description='url request time test')
parser.add_argument('URL', help='request url')
parser.add_argument('-t', '--time', action='store', dest='count', type=int, default=, help='request times')
args = parser.parse_args(argv)
benchmark(args.URL, args.count)
if __name__ == '__main__':
main(sys.argv[:])
ruby 本身也有 optparse 库用于解析参数,但需要手写生成 --help 的输出,而且需要对每个参数做相应的 callback。
效果如下:
获取http响应时间,pycurl,python
python抓取网页的例子:
#!/usr/bin/env python
import urllib2
html=urllib2.urlopen('http://www.jb200.com').read()
但是在实际工作中,这种写法是远远不够的,至少会遇到下面几个问题:
网络会出错,任何错误都可能。例如机器宕了,网线断了,域名出错了,网络超时了,页面没有了,网站跳转了,服务被禁了,主机负载不够了…
服务器加上了限制,只让常见浏览器访问
服务器加上了防盗链的限制
某些2B网站不管你HTTP请求里有没有Accept-Encoding头部,也不管你头部具体内容是什么,反正总给你发gzip后的内容
URL链接千奇百怪,带汉字的也罢了,有的甚至还有回车换行。
某些网站HTTP头部里有一个Content-Type,网页里有好几个Content-Type,更过分的是,各个Content-Type还不一样,最过分的是,这些Content-Type可能都不是正文里使用的Content-Type,从而导致乱码
网络链接很慢,乘分析几千个页面的时间。
Python本身的接口有点糙
错误处理和服务器限制
首先是错误处理。由于urlopen本身将大部分错误,甚至包括4XX和5XX的HTTP响应,也搞成了异常,因此我们只需要捕捉异常就好了。同时,我们也可以获取urlopen返回的响应对象,读取它的HTTP状态码。除此之外,在urlopen时,也需要设置timeout参数,以保证处理好超时。
例子:
#!/usr/bin/python
import urllib2
import socket
try:
f=urllib2.urlopen('http://www.jb200.com',timeout=10)
code=f.getcode()
ifcode<</span>200orcode>=300:
#你自己的HTTP错误处理
exceptException,e:
ifisinstance(e,urllib2.HTTPError):
print'http error: {0}'.format(e.code)
elifisinstance(e,urllib2.URLError)andisinstance(e.reason,socket.timeout):
print'url error: socket timeout {0}'.format(e.__str__())
else:
print'misc error: '+e.__str__()
如果是服务器的限制,一般都可以通过查看真实浏览器的请求来设置对应的HTTP头部,例如针对浏览器的限制,可以设置User-Agent头部,针对防盗链限制,可以设置Referer头部。
例子:
#!/usr/bin/env python
import urllib2
req=urllib2.Request('http://www.jb200.com',
headers={"Referer":"http://www.baidu.com",
"User-Agent":"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.68 Safari/534.24"
})
html=urllib2.urlopen(url=req,timeout=10).read()
对于采用Cookie来限制的网站,主要是涉及到登录和限流,没有什么通用的方法,只能看能否做自动登录或者分析Cookie的问题了。
二、URL与内容处理
URL里奇形怪状的格式只能个别分析,个别处理,逮到一个算一个。例如针对URL里可能有汉字,相对路径,以及回车换行之类的问题,我们可以先用urlparse模块的urljoin函数处理相对路径的问题,然后去掉乱七八糟的回车换行之类的玩意,最后用urllib2的quote函数处理特殊字符编码和转义的问题,生成真正的URL。
当然,在使用的过程中你会发现Python的urljoin和urlopen都有些问题,因此具体的代码我们在后面再给。
对于那些不管三七二十一就把gzip内容丢过来的,直接分析它的内容格式,不要管HTTP头部就好了。
代码: