来源: 【原创】网站抓包HttpWebRequest不返回Javascript生成的Cookie的解决办法 – 0ng_Ching_Tong – 博客园
前言:
最近在做中国移动爬虫的过程中,首先遇到的就是 在某个请求中,有一个名为“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代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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”文件中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
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获得执行结果
1
2
3
4
5
6
7
8
9
10
11
12
|
//设置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代码动态得到,直接 写死的话 也应该可以。
测试时间 > 构造时间 > 代码时间