在C#中使用WebClient有一种方法来redirect后获取网站的url?

使用WebClient类,我可以很容易地得到一个网站的标题:

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

我想存储url和页面标题。 但是,当按照以下链接进行操作时:

http://tinyurl.com/dbysxp

我显然希望获得我redirect到的url。

质询

有没有办法使用WebClient类来做到这一点?

我将如何使用HttpResponseHttpRequest

如果我明白这个问题,就比人们所说的要容易得多 – 如果你想让WebClient完成请求的所有细节(包括redirect),但是最后得到实际的响应URI,你可以inheritanceWebClient喜欢这个:

 class MyWebClient : WebClient { Uri _responseUri; public Uri ResponseUri { get { return _responseUri; } } protected override WebResponse GetWebResponse(WebRequest request) { WebResponse response = base.GetWebResponse(request); _responseUri = response.ResponseUri; return response; } } 

只要使用MyWebClient,您就可以使用WebClient。 在你做任何WebClient调用之后,你可以使用ResponseUri来获得实际的redirectURI。 如果你使用的是asynchronous的东西,你需要为GetWebResponse(WebRequest请求,IAsyncResult结果)添加一个类似的覆盖。

我知道这已经是一个回答的问题,但这对我来说很有用:

  HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://tinyurl.com/dbysxp"); request.AllowAutoRedirect = false; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); string redirUrl = response.Headers["Location"]; response.Close(); //Show the redirected url MessageBox.Show("You're being redirected to: "+redirUrl); 

干杯。! ;)

使用HttpWebRequest ,您可以将AllowAutoRedirect属性设置为false 。 发生这种情况时,状态码在300-399之间的任何响应都不会自动redirect。

然后,您可以从响应头中获取新的url,然后为新的url创build一个新的HttpWebRequest实例。

WebClient类 ,我怀疑你可以改变它的开箱即用,所以它不允许redirect。 你可以做的是从WebClient类派生一个类,然后重写GetWebRequestGetWebResponse方法来改变基本实现返回的WebRequest / WebResponse实例; 如果是HttpWebRequest ,则将AllowAutoRedirect属性设置为false 。 在响应中,如果状态码在300-399的范围内,则发出新的请求。

但是,我不知道你可以在GetWebRequest / GetWebResponse方法中发出一个新的请求,所以最好是只要有一个用HttpWebRequest / HttpWebResponse执行的循环,直到遵循所有的redirect。

我得到了Uri的redirect页面和页面内容。

 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(strUrl); request.AllowAutoRedirect = true; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); Stream dataStream = response.GetResponseStream(); strLastRedirect = response.ResponseUri.ToString(); StreamReader reader = new StreamReader(dataStream); string strResponse = reader.ReadToEnd(); response.Close(); 

如果您只对redirectURI感兴趣,可以使用以下代码:

 public static string GetRedirectUrl(string url) { HttpWebRequest request = (HttpWebRequest) HttpWebRequest.Create(url); request.AllowAutoRedirect = false; using (HttpWebResponse response = HttpWebResponse)request.GetResponse()) { return response.Headers["Location"]; } } 

该方法将返回

  • null – 在没有redirect的情况下
  • 一个相对的url – 在redirect的情况下

请注意using声明(或最终的response.close() )是必不可less的。 有关详细信息,请参阅MSDN Library 。 否则,当多次执行此代码时,可能会耗尽连接或超时。

HttpWebRequest.AllowAutoRedirect可以设置为false。 那么你必须在300范围内手动http状态码。

 // Create a new HttpWebRequest Object to the mentioned URL. HttpWebRequest myHttpWebRequest=(HttpWebRequest)WebRequest.Create("http://www.contoso.com"); myHttpWebRequest.MaximumAutomaticRedirections=1; myHttpWebRequest.AllowAutoRedirect=true; HttpWebResponse myHttpWebResponse=(HttpWebResponse)myHttpWebRequest.GetResponse(); 

WebClient类可以select遵循redirect。 设置该选项,你应该没问题。

确定这是真的hackish,但关键是使用HttpWebRequest,然后将AllowAutoRedirect属性设置为true。

这是一个非常黑客一起的例子

  HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://tinyurl.com/dbysxp"); req.Method = "GET"; req.AllowAutoRedirect = true; WebResponse response = req.GetResponse(); response.GetResponseStream(); Stream responseStream = response.GetResponseStream(); // Content-Length header is not trustable, but makes a good hint. // Responses longer than int size will throw an exception here! int length = (int)response.ContentLength; const int bufSizeMax = 65536; // max read buffer size conserves memory const int bufSizeMin = 8192; // min size prevents numerous small reads // Use Content-Length if between bufSizeMax and bufSizeMin int bufSize = bufSizeMin; if (length > bufSize) bufSize = length > bufSizeMax ? bufSizeMax : length; StringBuilder sb; // Allocate buffer and StringBuilder for reading response byte[] buf = new byte[bufSize]; sb = new StringBuilder(bufSize); // Read response stream until end while ((length = responseStream.Read(buf, 0, buf.Length)) != 0) sb.Append(Encoding.UTF8.GetString(buf, 0, length)); string source = sb.ToString();string title = Regex.Match(source, @"\<title\b[^>]*\>\s*(?<Title>[\s\S]*?)\</title\>",RegexOptions.IgnoreCase).Groups["Title"].Value; 

enter code here