网页抓取数据小工具-简化数值变量值

笔者出于兴趣或者工作需要,会经常对一些网站的数据进行数据抓取,对于像淘宝、携程、百度这类大型互联网公司的网站,出于安全或者性能考虑,常常会针对网站加入反抓取策略脚本。

在该类脚本中,常见的手法有以下几种:

1. 针对简单数值变量的值,会把它用一个数值表达式来表示,让你没办法一眼看穿它,如:_lkqr = - ((104 | 3525868) % 705192)

2. 把一个简单的数值,用手法1中两个变量进行运算,得到真正数值。如: _set = _lkqr + _lnz

3. 提供一个字符串转换函数,让你无法理解它给你的字符串的真正涵义。

4. 加入一些适当的废代码,让你很难抓住真正的逻辑

5. 把Js调用的方式,采用数组方式来调用。如window.document会写成window['document']

6. 其他。。。

在这篇文章中,我主要是想针对问题1做了一个简单的小程序,化复杂表达式为简单数值,提高分析效率。

 1             ExprEvalUtil expUtil = new ExprEvalUtil();
 2             Regex regex = new Regex(@"\({1,}((0x[0-9a-f]+)|(\d+))(\s*[\+\-\*\/\%\|\&\^\>\<]{1,2}\s*\(*[ \t]*((0x[0-9a-f]+)|(\d+))\s*\)*)+", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled);
 3             String jsContent = null;
 4             FileStream fs = new FileStream("d:\\somejs.js", FileMode.Open);
 5             using (TextReader reader = new StreamReader(fs))
 6             {
 7                 jsContent = reader.ReadToEnd();
 8             }
 9 
10             string result = regex.Replace(jsContent, m =>
11             {
12                 string value = m.Value;
13                 int lkValue = 0;
14                 int index = -1;
15                 while ((index = value.IndexOf('(', index + 1)) != -1)
16                 {
17                     lkValue++;
18                 }
19 
20                 int rkValue = 0;
21                 //index = 0;
22                 while ((index = value.IndexOf(')', index + 1)) != -1)
23                 {
24                     rkValue++;
25                 }
26 
27                 String preStr = "";
28                 if (rkValue < lkValue)
29                 {
30                     value = value.Remove(0, lkValue - rkValue);
31                     preStr = new String('(', lkValue - rkValue); 
32                 }
33 
34                 String postStr = "";
35                 if (rkValue > lkValue)
36                 {
37                     value = value.Remove(value.Length - rkValue + lkValue);
38                     postStr = new String(')', rkValue - lkValue);
39                 }
40 
41                 try
42                 {
43                    value = expUtil.Eval(value).ToString();
44                 }
45                 catch (Exception ex)
46                 {
47                     return m.Value;
48                 }
49 
50                 return preStr + value + postStr;
51             });
52 
53             Console.WriteLine(result);

其中的ExpEvalUtil代码,我利用了网上的一个Javascript解释器(Jussica)引擎实现,代码如下:

    public class ExprEvalUtil
    {
        private ScriptEngine engine = new ScriptEngine();

        public int Eval(string expr)
        {
            return (int)Convert.ChangeType(engine.Evaluate(expr), typeof(int));
        }
    }

通过上述代码进行一个处理后,你是不是觉得有点眼前一新的感觉了?

笔者实际上对后面几个问题解决,也有了新的思路,欢迎更多同学加入探讨

posted @ 2015-04-21 11:07  理查杨哥  阅读(441)  评论(0编辑  收藏  举报