如何从C#中获取网站标题

18

我正在回顾我的一些旧代码,偶然发现了一种根据网址获取网站标题的方法。但这并不是一个稳定的方法,因为它经常无法产生结果,有时甚至会产生错误的结果。此外,有时它无法显示标题中的某些字符,因为它们采用了替代编码。

是否有人对这个旧版本有改进的建议?

public static string SuggestTitle(string url, int timeout)
{
    WebResponse response = null;
    string line = string.Empty;

    try
    {
        WebRequest request = WebRequest.Create(url);
        request.Timeout = timeout;

        response = request.GetResponse();
        Stream streamReceive = response.GetResponseStream();
        Encoding encoding = System.Text.Encoding.GetEncoding("utf-8");
        StreamReader streamRead = new System.IO.StreamReader(streamReceive, encoding);

        while(streamRead.EndOfStream != true)
        {
            line = streamRead.ReadLine();
            if (line.Contains("<title>"))
            {
                line = line.Split(new char[] { '<', '>' })[2];
                break;
            }
        }
    }
    catch (Exception) { }
    finally
    {
        if (response != null)
        {
            response.Close();
        }
    }

    return line;
}

最后一点 - 我希望代码能够更快地运行,因为它会一直阻塞,直到页面被获取。如果我只能获取网站的标题而不是整个页面,那就太好了。

3个回答

52

一种更简单的获取内容的方法:

WebClient x = new WebClient();
string source = x.DownloadString("http://www.singingeels.com/");

更简单、更可靠的获取标题的方法:

string title = Regex.Match(source, @"\<title\b[^>]*\>\s*(?<Title>[\s\S]*?)\</title\>",
    RegexOptions.IgnoreCase).Groups["Title"].Value;

在使用WebClient时,有没有设置超时的方法? - Morten Christiansen
我认为唯一需要补充的是,在模式中必须添加 @(用于转义内容),即:@"<title\b[^>]>\s(?<Title>[\s\S]*?)</title>" - netadictos
为了给WebClient类添加超时(和其他东西),这个指南提供了一个很好的解决方案:http://codegator.com/mcook/archive/2006/07/17/extending-webclient-using-c.aspx - Morten Christiansen

10
也许这个建议会为您打开一扇新世界的大门。我也曾有过这个问题,并找到了解决方法。
http://html-agility-pack.net/?z=codeplex下载“Html Agility Pack”。
或者去Nuget:https://www.nuget.org/packages/HtmlAgilityPack/,并添加此引用。
在代码文件中添加以下内容:
using HtmlAgilityPack;

请在您的方法中编写以下代码:

var webGet = new HtmlWeb();
var document = webGet.Load(url);    
var title = document.DocumentNode.SelectSingleNode("html/head/title").InnerText;

参考资料:

如何使用HtmlAgilityPack在C#中从URL中抓取元数据 HtmlAgilityPack获取标题和元标记


-1

为了完成这个任务,你需要做一些事情。

  • 将你的应用程序线程化,以便可以同时处理多个请求,并最大化正在进行的HTTP请求的数量。
  • 在异步请求期间,仅下载您想要返回的数据量,您可以在数据返回时对其进行解析
  • 可能需要使用正则表达式来提取标题名称

我以前用SEO机器人做过这个,我能够一次处理近10,000个请求。你只需要确保每个Web请求都可以在一个线程中自包含即可。


如果你想同时处理10,000个请求,肯定不希望为每个请求分配一个线程!(涉及的堆栈会像疯了一样占用你的内存。)使用异步API将并行化操作,而不会为每个请求消耗一个线程。 - Jon Skeet
这是一个无关紧要的问题,因为我只需要一次执行一个请求。速度的需求是因为用户正在等待回复。 - Morten Christiansen
@Jon,就像我说的那样,我的是一个分析SEO的机器人,显然你希望在每次分析时对请求的数量设置限制,以保持内存合理。但是10,000是一个压力测试场景。而异步则是建议仅下载标题的方法。 - Nick Berardi
@Morten,我只是根据你给我的非常基本的细节来进行操作。你说你想让它运行得更快,并且你只想下载头文件,异步请求是限制下载大小的最佳方式,因为当你找到答案时,你可以停止这个过程。 - Nick Berardi
@Jon,你使用了一个非常明确的陈述,即你不希望每个请求都有一个线程,这可能是正确的,但你忘记了伴随每个请求进行的分析。如果分析处理器是单线程的话,将会有可怕的队列积压。 - Nick Berardi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接