我们知道网页重定向有3种方式
1.http重定向
2.mata tag重定向
3.js重定向
如果用http client,可以搞定1和2,但是对于3是无能为力的。
要做到js重定向必须依赖浏览器。但是selenium chromedriver并没有直接提供获取重定向链的功能,可以通过performance log来获取。不幸的是chrome最新版已经对应w3c,但是selenium chromedriver的安定版还没有对应。这个功能要4.0版才有,目前只有4.0alpha04的版本,因为很着急,暂时用这个版本,目前还没有发现问题。
取到了log后,该如何分析,网上没有找到资料,经过艰苦的分析,得到下面代码片段,与大家分享
这段代码可以分析重定向链的url,重定向原因,状态码
var redirectChain = new List<RedirectPage>();
var logs = driver.Manage().Logs.GetLog("performance"); //all your logs with redirects will be here
var redirectPage = new RedirectPage();
RedirectPage redirectPage=null;
string frameId = null;
string requestId = null;
foreach (LogEntry log in logs)
{
JObject msg = JObject.Parse(log.Message);
switch ((string)msg["message"]["method"])
{
case "Network.requestWillBeSent":
if (frameId == null || (string)msg["message"]["params"]["frameId"] == frameId && (string)msg["message"]["params"]["loaderId"] == (string)msg["message"]["params"]["requestId"])
{
if (frameId == null)
{
if ((string)msg["message"]["params"]["frameId"]== (string)msg["webview"])
{
frameId = (string)msg["message"]["params"]["frameId"];
}
else
{
break;
}
}
if (msg["message"]["params"]["redirectResponse"] !=null)
{
var result = redirectChain.Last();
if (result != null)
{
result.reason = "Location";
result.status = (int)msg["message"]["params"]["redirectResponse"]["status"];
result.squidError = (string)msg["message"]["params"]["redirectResponse"]["headers"]["X-Squid-Error"];
}
}
redirectPage = new RedirectPage();
requestId = (string)msg["message"]["params"]["requestId"];
redirectPage.url = (string)msg["message"]["params"]["documentURL"];
redirectChain.Add(redirectPage);
}
break;
case "Network.responseReceived":
if (requestId == (string)msg["message"]["params"]["requestId"])
{
redirectPage.status = (int)msg["message"]["params"]["response"]["status"];
redirectPage.squidError = (string)msg["message"]["params"]["response"]["headers"]["X-Squid-Error"];
}
break;
case "Page.frameScheduledNavigation":
if( frameId == (string)msg["message"]["params"]["frameId"])
{
int lastIndex = redirectChain.Count-1;
if (lastIndex > 0 && redirectChain[lastIndex].url == (string)msg["message"]["params"]["url"])
{
redirectChain[lastIndex-1].reason = (string)msg["message"]["params"]["reason"];
}
else
{
redirectChain[lastIndex].reason = (string)msg["message"]["params"]["reason"];
}
}
break;
}
}
结果放到redirectChain 里面,RedirectPage的结构如下
//重定向页面状态
public class RedirectPage
{
public string url;
public int status;
public string squidError;
public string reason;
}
说实话这个代码很奇怪,特别是获取重定向原因的代码,最后只能这样写,没有其他办法。找到数据之间的关系花了不少时间,这个日志本来就不是为获取重定向链准备的。