前言: 最近在做中國移動爬蟲的過程中,首先遇到的就是 在某個請求中,有一個名為“WT_PFC"的cookie鍵值是由前端JavaScript生成的,沒有進入到HttpWebResponse中,也就是說C#不回去執行客戶端腳本 ,HttpWebRequest不是一個真正意義上的web瀏覽器,它只會下載 ...
前言:
最近在做中國移動爬蟲的過程中,首先遇到的就是 在某個請求中,有一個名為“WT_PFC"的cookie鍵值是由前端JavaScript生成的,沒有進入到HttpWebResponse中,也就是說C#不回去執行客戶端腳本 ,HttpWebRequest不是一個真正意義上的web瀏覽器,它只會下載它所請求的地址的html信息,它永遠不會去執行JavaScript或者ajax。
但是由於其他的請求的Request需要Sent該Cookie,所以查了很多資料,基本上只能 重新構建 js 演算法 或者使用 WebBrowser自動去執行頁面js, 但這些都不是最好最快的方法。我採用的是以下的
C# 代碼動態編譯JavaScript代碼的方式得出 JavaScript函數被調用之後的 返回值。
1.Cookie(WT_FPC):
2. 通過HttpWatch查到的生成該cookie的js代碼:
public static function GetWT_FPC(){ var $t = "2"; var $u = new Date(); var $v = new Date($u.getTime() + 315360000000); var $w = new Date($u.getTime()); if ($t.length < 10) { var $x = $u.getTime().toString(); for (var i = 2; i <= (32 - $x.length); i++) $t += Math.floor(Math.random() * 16.0).toString(16); $t += $x; }; $t = encodeURIComponent($t); return "WT_FPC=id=" + $t + ":lv=" + $u.getTime().toString() + ":ss=" + $w.getTime().toString() ; };
請註意:請按以上的格式書寫 腳本函數,即加上"public static ".
3.JsHelper(動態編譯Js代碼):
我把上面js代碼放到本地"WT_FPC.js"文件中
public static class JsHelper { /// <summary> /// 執行JS方法 /// </summary> /// <param name="methodName">方法名</param> /// <param name="para">參數</param> /// <returns></returns> public static string GetJsMethd(string methodName, object[] para) { string path = AppDomain.CurrentDomain.BaseDirectory + "WT_FPC.js"; string str2 = File.ReadAllText(path); StringBuilder sb = new StringBuilder(); sb.Append("package aa{"); sb.Append(" public class JScript {"); sb.Append(str2); sb.Append("}}"); CompilerParameters parameters = new CompilerParameters(); parameters.GenerateInMemory = true; CodeDomProvider _provider = new Microsoft.JScript.JScriptCodeProvider(); CompilerResults results = _provider.CompileAssemblyFromSource(parameters, sb.ToString()); Assembly assembly = results.CompiledAssembly; Type _evaluateType = assembly.GetType("aa.JScript"); object obj = _evaluateType.InvokeMember("GetWT_FPC", BindingFlags.InvokeMethod, null, null, para); return obj.ToString(); } }
註意:以上的helper代碼如果報錯的話,99%都是由於 Js代碼的問題,即js代碼不規範或者 變數缺少定義之類。
4. C#代碼調用helper獲得執行結果
//設置Cookie"WT_FPC" string wt_fpc = JsHelper.GetJsMethd("GetWT_FPC", null); CookieCollection hcc = new CookieCollection(); Cookie wtcookie = new Cookie() { Expires = DateTime.Now.AddYears(10), Path = "/", Domain = ".10086.cn", Name = "WT_FPC", Value = wt_fpc.Substring(wt_fpc.IndexOf('=') + 1, wt_fpc.Length - 7)// }; hcc.Add(wtcookie); HttpHelperNew.cookie.Add(wtcookie);
5.完結! 小經驗: 有時候 JavaScript前端生成的cookie,有時候 伺服器端並不 校驗,也就是,如果把這個cookie值不通過js代碼動態得到,直接 寫死的話 也應該可以。