获取HTTP请求的TTFB(第一个字节的时间)

时间:2009-04-13 16:44:07

标签: python http urllib2

这是一个加载url并捕获响应时间的python脚本:

import urllib2
import time

opener = urllib2.build_opener()
request = urllib2.Request('http://example.com')

start = time.time()
resp = opener.open(request)
resp.read()
ttlb = time.time() - start

由于我的计时器包裹着整个请求/响应(包括read()),这将给我TTLB(时间到最后一个字节)。

我还想获得TTFB(到第一个字节的时间),但我不知道从哪里开始/停止我的计时。 urllib2是否足以让我添加TTFB计时器?如果是这样,他们会去哪里?

4 个答案:

答案 0 :(得分:6)

您应该使用pycurl,而不是urllib2

  1. 安装pyCurl
    你可以使用pip / easy_install,或者从源代码安装它。

    easy_install pyCurl

    也许你应该是超级用户。

  2. 用法:

    import pycurl
    import sys 
    import json
    
    WEB_SITES = sys.argv[1]
    
    def main():
        c = pycurl.Curl()
        c.setopt(pycurl.URL, WEB_SITES)              #set url
        c.setopt(pycurl.FOLLOWLOCATION, 1)  
        content = c.perform()                        #execute 
        dns_time = c.getinfo(pycurl.NAMELOOKUP_TIME) #DNS time
        conn_time = c.getinfo(pycurl.CONNECT_TIME)   #TCP/IP 3-way handshaking time
        starttransfer_time = c.getinfo(pycurl.STARTTRANSFER_TIME)  #time-to-first-byte time
        total_time = c.getinfo(pycurl.TOTAL_TIME)  #last requst time
        c.close()
    
        data = json.dumps({'dns_time':dns_time,         
                           'conn_time':conn_time,        
                           'starttransfer_time':starttransfer_time,    
                           'total_time':total_time})
        return data
    
    if __name__ == "__main__":    
        print main()
    

答案 1 :(得分:2)

使用您当前的open / read对,在两者之间只有一个其他时间点。

open()调用应负责实际发送HTTP请求,并且应该(AFAIK)在发送后立即返回,为您的应用程序准备好通过read()实际读取响应。

从技术上讲,长时间的服务器响应可能会使您的应用程序阻止调用read(),在这种情况下,这不是TTFB。

然而,如果数据量很小,那么TTFB和TTLB之间无论如何都不会有太大差异。对于大量数据,只需测量read()返回第一个可能的最小块的时间。

答案 2 :(得分:1)

默认情况下,urllib2中的HTTP打开实现在执行读取时没有回调。 HTTP协议的OOTB开启者是urllib2.HTTPHandler,它使用httplib.HTTPResponse通过套接字进行实际读取。

理论上,您可以编写自己的HTTPResponse和HTTPHandler子类,并使用install_opener将其作为默认开启者安装到urllib2中。这将是非常重要的,但如果您基本上复制并粘贴标准库中的当前HTTPResponse实现并调整其中的begin()方法以在从套接字开始读取时执行某些处理或回调,那么这并非极其简单。 / p>

答案 3 :(得分:1)

要获得良好的接近度,您必须阅读(1)。并弄乱时间。

对我来说效果很好。 你应该记住的事情:python可能会在read(1)的调用中加载多个字节。取决于它的内部缓冲区。但我认为大多数工具的行为都不准确。

import urllib2
import time

opener = urllib2.build_opener()
request = urllib2.Request('http://example.com')

start = time.time()
resp = opener.open(request)
# read one byte
resp.read(1)
ttfb = time.time() - start
# read the rest
resp.read()
ttlb = time.time() - start