.NET Web爬虫需要测量HttpWebResponse的时间到第一个字节

时间:2014-07-05 07:44:32

标签: .net httpwebrequest httpresponse webrequest httpwebresponse

我编写了一个网络抓取工具应用程序来监控网站,检查问题。每当它访问一个页面时,我想捕获时间到第一个字节(即,发出请求和接收响应的第一个字节之间的时间)。 TTFB尽可能接近测量服务器渲染页面所需的时间。

下面是我执行此操作的代码,但结果看起来不正确。 TTFB通常与完整响应时间完全相同或少一点。我错过了什么?

HttpWebResponse webResponse = null;

var stopWatch = new Stopwatch();
stopWatch.Start();
try
{
    var webRequest = (HttpWebRequest)HttpWebRequest.Create(requestUrl);
    webRequest.Method = "get";

    webRequest.AllowAutoRedirect = false;
    webRequest.UserAgent = userAgent;
    webRequest.Accept = "*/*";
    webRequest.KeepAlive = true;
    webRequest.CookieContainer = CookieContainer;

    webResponse = (HttpWebResponse)webRequest.GetResponse();

    responseTimeToFirstByte = Convert.ToInt32(stopWatch.ElapsedMilliseconds);

    using (var responseStream = new StreamReader(webResponse.GetResponseStream(), System.Text.Encoding.ASCII))
    {
        bodyContent = responseStream.ReadToEnd();
        stopWatch.Stop();
    }

    webResponse.Close();
    responseTimeFull = Convert.ToInt32(stopWatch.ElapsedMilliseconds);
}

1 个答案:

答案 0 :(得分:4)

你没有遗漏任何东西。只有当框架已经被缓冲和解析时,框架才会通知响应。

HttpWebResponse对象已经设置了有关HTTP标头的信息,因此数据已经被重新编译和解析。也许发送一个巨大的文件你可能会发现不同,我不完全确定。

如果您想测量TFB,可以使用Socket或更好的TcpClient并发送精心设计的HTTP请求,然后测量返回数据的时间:

Byte[] buffer = new Byte[1024];
Int32 readed = -1;
TcpClient client = new TcpClient();
Stopwatch watch = new Stopwatch();
List<Int64> readTimes = new List<Int64>();

watch.Start();
await client.ConnectAsync(<IP address>, <Port>);
using(var stream = client.GetStream())
using (var ms = new MemoryStream())
using (var sw = new StreamWriter(stream, Encoding.ASCII))
{
    sw.WriteLine("GET /the/path/to/your/resource HTTP/1.1");
    sw.WriteLine("Host: yourdomainname.com");
    sw.WriteLine("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
    sw.WriteLine();
    await sw.FlushAsync();

    while(readed != 0)
    {
        readed = await stream.ReadAsync(buffer,0,buffer.Length);
        readTimes.Add(watch.ElapsedMilliseconds);
        ms.Write(buffer,0,readed);
    }

    watch.Stop();
}

(警告,此代码未经过测试)

在此代码中,“readTimes”中的第一个值将是您的TFB,最后一个值是总时间。

干杯。