如何在不下载所有页面源的情况下获取网页标题

quo*_*ian 6 c# httpwebrequest

我正在寻找一种方法,可以让我获得网页的标题并将其存储为字符串.

但是到目前为止我找到的所有解决方案都涉及下载页面的源代码,这对于大量的网页来说并不实用.

我能看到的唯一方法是限制字符串的长度,或者只有在到达标签时才下载一定数量的字符或停止,但这显然仍然很大?

谢谢

new*_*rey 16

由于<title>标签位于HTML本身,因此无法下载文件以找到"只是标题".你应该可以下载文件的一部分,直到你读入<title>标签或</head>标签,然后停止,但你仍然需要下载(至少一部分)文件.

这可以通过HttpWebRequest/ HttpWebResponse并从响应流中读取数据来完成,直到我们读取<title></title>块或</head>标记.我加了</head>标签检查,因为,在有效的HTML,标题块必须在头块中出现-所以,这个检查我们绝不会在解析任何情况下,整个文件(除非没有头块,当然).

以下应该能够完成这个任务:

string title = "";
try {
    HttpWebRequest request = (HttpWebRequest.Create(url) as HttpWebRequest);
    HttpWebResponse response = (request.GetResponse() as HttpWebResponse);

    using (Stream stream = response.GetResponseStream()) {
        // compiled regex to check for <title></title> block
        Regex titleCheck = new Regex(@"<title>\s*(.+?)\s*</title>", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        int bytesToRead = 8092;
        byte[] buffer = new byte[bytesToRead];
        string contents = "";
        int length = 0;
        while ((length = stream.Read(buffer, 0, bytesToRead)) > 0) {
            // convert the byte-array to a string and add it to the rest of the
            // contents that have been downloaded so far
            contents += Encoding.UTF8.GetString(buffer, 0, length);

            Match m = titleCheck.Match(contents);
            if (m.Success) {
                // we found a <title></title> match =]
                title = m.Groups[1].Value.ToString();
                break;
            } else if (contents.Contains("</head>")) {
                // reached end of head-block; no title found =[
                break;
            }
        }
    }
} catch (Exception e) {
    Console.WriteLine(e);
}
Run Code Online (Sandbox Code Playgroud)

更新:更新了原始源代码示例以使用已编译Regexusing声明,以Stream获得更高的效率和可维护性.

  • 这是一个很棒的代码解决方案,谢谢。仅供参考 - 编译正则表达式的问题是它在这里并没有真正的帮助,因为您为每个请求编译正则表达式。最好在运行时编译一次,然后在该方法中使用它。编译需要一些时间和更多内存,但对于大量(100mb+)文档或循环(数十万)来说非常有用。未编译的正则表达式会被缓存,并且对于文本的大小不会产生太大的影响。+1 (2认同)