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

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

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

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));

        }

    }

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

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

你可能感兴趣的:(网页抓取)