zoukankan      html  css  js  c++  java
  • 【原创】网站抓包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){ 
                } 
    

      

  • 相关阅读:
    VOA 2009/11/02 DEVELOPMENT REPORT In Kenya, a Better Life Through Mobile Money
    2009.11.26教育报道在美留学生数量创历史新高
    Java中如何实现Tree的数据结构算法
    The Python Tutorial
    VOA HEALTH REPORT Debate Over New Guidelines for Breast Cancer Screening
    VOA ECONOMICS REPORT Nearly Half of US Jobs Now Held by Women
    VOA ECONOMICS REPORT Junior Achievement Marks 90 Years of Business Education
    VOA 2009/11/07 IN THE NEWS A Second Term for Karzai; US Jobless Rate at 10.2%
    Ant入门
    Python 与系统管理
  • 原文地址:https://www.cnblogs.com/x-poior/p/5396353.html
Copyright © 2011-2022 走看看