在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
类来做到这一点?
我将如何使用HttpResponse
和HttpRequest
?
如果我明白这个问题,就比人们所说的要容易得多 – 如果你想让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
类派生一个类,然后重写GetWebRequest
和GetWebResponse
方法来改变基本实现返回的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