日期:2014-05-18  浏览次数:20909 次

使用C#访问百度指数:分析请求数据(1)

使用C#访问百度指数:分析请求数据(1)
2010年06月12日
  
  看到帖子有网友问如何使用C#程序访问百度指数(index.baidu.com),研究了下,写了个简单的Demo实现此功能,欢迎各位朋友指正。
  由于百度指数是以Flash的形式展现出来的,不方便直接取到,按常理,我们需要分析发送到服务器的数据和返回的结果。
  我使用的抓包工具是HTTP Analyzer,通过查看Post Data,可以看到客户端是发送了一个Post请求到http://index.baidu.com/gateway.php
  
  发送的数据是一个AMF Message
  
  那么我们需要研究下我们如何能让我们的程序发送出相同的请求。
  再此之前我们需要了解下AMF的概念,AMF是Adobe公司开发的数据交互和远程过程调用的协议,全称为Action Message Format,很类似于WebService。但WebService传递的是XML文本数据,而AMF使用Http传输的是二进制数据。 AMF中主要使用的数据类型如下:
  public enum DataType { Number = 0, Boolean = 1, String = 2, UntypedObject = 3, MovieClip = 4, Null = 5, Undefined = 6, ReferencedObject = 7, MixedArray = 8, End = 9, Array = 10,//0x0A Date = 11,//0x0B LongString = 12,//0x0C TypeAsObject = 13,//0x0D Recordset = 14,//0x0E Xml = 15,//0x0F TypedObject = 16,//0x10 AMF3data = 17//0x11 } 我们看下向服务器发送的AMF Message信息,HEX显示如下
  
  这些二进制数据的分析如下
  0003 说明使用的AMF版本,目前AMF有两个版本,0000 表示 AMF0,0003表示AMF3
  0000 表示AMF Header的数量0
  0001 表示AMF Body的数量1
  0017 表示调用的方法的长度占23个字节(17的16进制就是23)
  接下来
  4461 7461 4163 6365 7373 6f72 2e67 6574 496e 6465 7865 73
  这23个字节表示调用服务器端的方法是DataAccessor.getIndexes(44的16进制就是68,也就是D,后面不再做类似解释)
  接下来的 00 022f 31 表示target作为标识实现请求和响应的联系,一般是自增整数。00表示数据类型为Number,02表示长度为两个字节,2f 31其实就是/1
  00 0000 2d Body的长度为Number类型,长度为45
  0a 0000 0003 0a表示数组类型(类似于C#中的Dictionary,键值对,键总是string类型),长度为3
  数组的第一部分
  0200 0ce5 a881 e8bf 85e6 9599 e882 b2 02表示字符串类型,0c表示此字符串长度为12,后面的e5 a881 e8bf 85e6 9599 e882 b2
  表示传递的数据,可以用下段代码查看
  byte[] buffer = new byte[] { 0xe5, 0xa8, 0x81, 0xe8, 0xbf, 0x85, 0xe6, 0x95, 0x99, 0xe8, 0x82, 0xb2 };
  string str = System.Text.Encoding.UTF8.GetString(buffer);
  Console.Write(str); //广告
  数组的第二部分
  02 0001 30 字符串0,不知道有什么意义
  数组的第三部分
  02 0012 3230 3130 2d36 2d31 7c32 3031 302d 362d 3131
  长度为18的字符串,内容为2010-6-1|2010-6-11
  至此,请求的数据我们已经分析完毕,再简单说下返回的数据(Response Content)
  
  返回的AMF Message当然也包括Header和Body(数组类型)
  Body的Target为/1/onResult
  Body的Content包括
  key String类型 就是我们传进去的关键词
  area Number类型 0
  areaName String类型 可以用上面的代码看到内容,就是全国
  userIndexes String类型 这里都是百度指数(用户关注度),用逗号分隔开
  mediaIndexes String类型 这里都是媒体指数(媒体关注度),用逗号分隔开(由于图中userIndexes 占位较多,所以未显示出来,在userIndexes数据下方)
  如果想得到最后一天的百度指数,只要找到mediaIndexes前面最后一个逗号后跟的数字即可(当然要排除mediaIndexes本身数据类型及长度的占位字节)
  文章参考了
  AMF学习1数据类型 
  http://www.cnblogs.com/studyzy/archive/2008/04/09/ 1143685.html
  AMF学习2远程调用的封装 
  http://www.cnblogs.com/studyzy/archive/2008/04/11/ 1147658.html