2009-04-13 40 views
5

下面是加載一個URL並捕獲響應時間的python腳本:獲取TTFB(時間,直到第一個字節)的HTTP請求

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 

由於我的計時器是圍繞整個請求/響應包(包括讀()),這會給我TTLB(到最後一個字節的時間)。

我也想得到TTFB(第一個字節的時間),但不知道在哪裏開始/停止我的時間。 urllib2足夠精細,可以添加TTFB定時器嗎?如果是這樣,他們會去哪裏?

回答

2

使用您當前的open/read對,只有一個可能的時間點 - 兩者之間。

open()調用應該負責實際發送HTTP請求,並且應該在發送後立即返回,準備好讓應用程序通過read()實際讀取響應。

從技術上講,長時間的服務器響應可能會讓您的應用程序阻塞read(),在這種情況下,這不是TTFB。

但是,如果數據量很小,TTFB和TTLB之間不會有太大的差別。對於大量數據,只需測量read()返回第一個儘可能小的塊所花費的時間。

+0

感謝。做一些像「連接時間」這樣的開放式步驟可能會讓我得到我需要的東西(儘管不是真正的TTFB) – 2009-04-13 18:19:02

1

默認情況下,執行讀取時,urllib2中的HTTP開放實現沒有回調。 HTTP協議的OOTB開啓器是urllib2.HTTPHandler,它使用httplib.HTTPResponse通過套接字進行實際讀取。

理論上,您可以編寫自己的HTTPResponse和HTTPHandler的子類,並使用install_opener將其作爲默認開啓者安裝到urllib2中。這將是非平凡的,但並不令人生厭,所以如果您從標準庫複製並粘貼當前的HTTPResponse實現,並在那裏調整begin()方法以在從套接字讀取開始時執行一些處理或回調。

1

爲了獲得良好的接近度,您必須閱讀(1)。並且消磨時間。

它對我來說工作得很好。 你應該記住的ony事情: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 
5

你應該使用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 
    

    如果 == 「主要」:
    打印的main()