【原創】網站抓包HttpWebRequest不返回Javascript生成的Cookie的解決辦法


前言:

最近在做中國移動爬蟲的過程中,首先遇到的就是 在某個請求中,有一個名為“WT_PFC"的cookie鍵值是由前端JavaScript生成的,沒有進入到HttpWebResponse中。事實上,C#不會去執行客戶端腳本 ,用到的HttpWebRequest不是一個真正意義上的web瀏覽器,它只會下載它所請求的地址的html信息,它永遠不會去執行JavaScript或者ajax,同時WebClient這個類間接地也是調用了HttpWebRequest來請求的,所以結論是一致的。

但是由於其他的請求的Request需要Sent該Cookie,所以查了很多資料,基本上只能 重新構建 js 算法 或者使用 WebBrowser自動去執行頁面js

IHTMLWindow2 win = (IHTMLWindow2)webBrowser1.Document.Window.DomWindow;
            string s = @"function confirm() {";
            s += @"return true;";
            s += @"}";
            s += @"function alert() {}";
            win.execScript(s, "javascript");

, 但這些都不是最好最快的方法。我采用的是以下的

C# 代碼動態編譯JavaScript代碼的方式得出 JavaScript函數被調用之后的 返回值。

 

1.Cookie(WT_FPC):

 

2. 通過HttpWatch查到的生成該cookie的js代碼,我提煉出了生成該Cookie的方法,並按格式寫成如下形式:

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代碼動態得到,直接 寫死的話 也應該可以。

6. 其他:

一:如果需要用C#執行前端js 函數計算的結果,比如 前端js的加密結果,在能找到js代碼前提下,可以把js寫在本地的html 頁面里面,然后C#代碼去訪問 即可。so easy!

二: Java 中使用WebClient獲取js執行完返回的值。

try{ 
        WebClient webClient = new WebClient(BrowserVersion.FIREFOX_24); 
        //設置webClient的相關參數 
        webClient.getOptions().setJavaScriptEnabled(true); 
        webClient.getOptions().setCssEnabled(false); 
        webClient.setAjaxController(new NicelyResynchronizingAjaxController()); 
        //webClient.getOptions().setTimeout(50000); 
        webClient.getOptions().setThrowExceptionOnScriptError(false); 
        //模擬瀏覽器打開一個目標網址 
            HtmlPage rootPage= webClient.getPage(url); 
            System.out.println("為了獲取js執行的數據 線程開始沉睡等待"); 
            Thread.sleep(3000);//主要是這個線程的等待 因為js加載也是需要時間的 
            System.out.println("線程結束沉睡"); 
            String html = rootPage.asText(); 
            System.out.println(html); 
            }catch(Exception e){ 
            } 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM