我的数据库中有一个表,其中包含一些网站的URL.我必须打开这些URL并验证这些页面上的一些链接.问题是某些URL被重定向到其他URL.我的逻辑是没有这样的URL.
有什么方法可以通过我的原始URL字符串并重新获取重定向的URL?
示例:我正在尝试使用此URL:http: //individual.troweprice.com/public/Retail/xStaticFiles/FormsAndLiterature/CollegeSavings/trp529Disclosure.pdf
它被重定向到这个:http: //individual.troweprice.com/staticFiles/Retail/Shared/PDFs/trp529Disclosure.pdf
我试着使用以下代码:
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(Uris); req.Proxy = proxy; req.Method = "HEAD"; req.AllowAutoRedirect = false; HttpWebResponse myResp = (HttpWebResponse)req.GetResponse(); if (myResp.StatusCode == HttpStatusCode.Redirect) { MessageBox.Show("redirected to:" + myResp.GetResponseHeader("Location")); }
当我执行上面的代码时,它给了我HttpStatusCodeOk
.我很惊讶它为什么不考虑重定向.如果我在Internet Explorer中打开该链接,它将重定向到另一个URL并打开PDF文件.
有人可以帮助我理解为什么它不能正常运行示例URL吗?
顺便说一句,我检查了Hotmail的URL(http://www.hotmail.com)并正确返回重定向的URL.
谢谢,
此函数将返回链接的最终目标 - 即使存在多个重定向.它不考虑基于JavaScript的重定向或META重定向.请注意,之前的解决方案没有处理绝对和相对URL,因为LOCATION标头可能返回类似"/ newhome"的内容,您需要与提供该响应的URL结合使用以识别完整的URL目标.
public static string GetFinalRedirect(string url) { if(string.IsNullOrWhiteSpace(url)) return url; int maxRedirCount = 8; // prevent infinite loops string newUrl = url; do { HttpWebRequest req = null; HttpWebResponse resp = null; try { req = (HttpWebRequest) HttpWebRequest.Create(url); req.Method = "HEAD"; req.AllowAutoRedirect = false; resp = (HttpWebResponse)req.GetResponse(); switch (resp.StatusCode) { case HttpStatusCode.OK: return newUrl; case HttpStatusCode.Redirect: case HttpStatusCode.MovedPermanently: case HttpStatusCode.RedirectKeepVerb: case HttpStatusCode.RedirectMethod: newUrl = resp.Headers["Location"]; if (newUrl == null) return url; if (newUrl.IndexOf("://", System.StringComparison.Ordinal) == -1) { // Doesn't have a URL Schema, meaning it's a relative or absolute URL Uri u = new Uri(new Uri(url), newUrl); newUrl = u.ToString(); } break; default: return newUrl; } url = newUrl; } catch (WebException) { // Return the last known good URL return newUrl; } catch (Exception ex) { return null; } finally { if (resp != null) resp.Close(); } } while (maxRedirCount-- > 0); return newUrl; }
您提到的URL使用JavaScript重定向,该重定向仅重定向浏览器.因此,没有简单的方法来检测重定向.
为了正确(HTTP状态代码和位置:)重定向,您可能想要删除
req.AllowAutoRedirect = false;
并使用获取最终的URL
myResp.ResponseUri
因为可以有多个重定向.
更新:有关重定向的更多说明:
将浏览器重定向到另一个URL的方法不止一种.
第一种方法是使用3xx HTTP状态代码和Location:标头.这是神想要HTTP重定向工作的方式,也被称为"一种真正的方式".此方法适用于所有浏览器和抓取工具.
然后是魔鬼的方式.这些包括元刷新,Refresh:标头和JavaScript.虽然这些方法适用于大多数浏览器,但它们肯定不能保证工作,偶尔会导致奇怪的行为(又称打破后退按钮).
大多数网络抓取工具(包括Googlebot)都会忽略这些重定向方法,您也应该这样做.如果您必须检测所有重定向,则必须解析META标记的HTML,在响应中查找Refresh:标头,并评估Javascript.祝最后一个好运.
使用此代码来重定向网址
public void GrtUrl(string url) { HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url); webRequest.AllowAutoRedirect = false; // IMPORTANT webRequest.Timeout = 10000; // timeout 10s webRequest.Method = "HEAD"; // Get the response ... HttpWebResponse webResponse; using (webResponse = (HttpWebResponse)webRequest.GetResponse()) { // Now look to see if it's a redirect if ((int)webResponse.StatusCode >= 300 && (int)webResponse.StatusCode <= 399) { string uriString = webResponse.Headers["Location"]; Console.WriteLine("Redirect to " + uriString ?? "NULL"); webResponse.Close(); // don't forget to close it - or bad things happen! } } }