有網(wǎng)友問如何使用C#程序訪問百度指數(shù)(網(wǎng)站的站長對這個指標(biāo)一定不陌生)。如下圖,顯示了CSDN的用戶關(guān)注度和媒體關(guān)注度。但很可惜的是,用戶只能通過瀏覽的方式得到某天的指數(shù),如果想批量檢查多個關(guān)鍵詞的百度指數(shù),就很麻煩了。而且如果想得到具體每天的數(shù)值也不是那么容易。
正好自己也有需要,所以研究了下,寫了個簡單的Demo實現(xiàn)此功能,歡迎各位朋友指正。
由于百度指數(shù)是以Flash的形式在客戶端展現(xiàn)出來的,不方便直接取到,開始我以為要用C#程序和Flash客戶端交互。但按常理,我們需要分析發(fā)送客戶度請求是發(fā)送到服務(wù)器的數(shù)據(jù)和返回的響應(yīng)結(jié)果(其實基本所有的外掛都是這樣做的)。
我使用的抓包工具是HTTP Analyzer,通過查看Post Data,可以看到客戶端是發(fā)送了一個Post請求到http://index.baidu.com/gateway.php
發(fā)送的數(shù)據(jù)是一個AMF Message
那么我們需要研究下我們?nèi)绾文茏屛覀兊某绦虬l(fā)送出相同的請求。
再此之前我們需要了解下AMF的概念,AMF是Adobe公司開發(fā)的數(shù)據(jù)交互和遠程過程調(diào)用的協(xié)議,全稱為Action Message Format,很類似于WebService。但WebService傳遞的是XML文本數(shù)據(jù),而AMF使用Http傳輸?shù)氖嵌M制數(shù)據(jù)。
AMF中主要使用的數(shù)據(jù)類型如下:
+ expand sourceview plaincopy to clipboardprint?
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
}
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
}
我們看下向服務(wù)器發(fā)送的AMF Message信息,HEX顯示如下
這些二進制數(shù)據(jù)的分析如下
0003 說明使用的AMF版本,目前AMF有兩個版本,0000 表示 AMF0,0003表示AMF3
0000 表示AMF Header的數(shù)量0
0001 表示AMF Body的數(shù)量1
0017 表示調(diào)用的方法的長度占23個字節(jié)(17的16進制就是23)
接下來
4461 7461 4163 6365 7373 6f72 2e67 6574 496e 6465 7865 73
這23個字節(jié)表示調(diào)用服務(wù)器端的方法是DataAccessor.getIndexes(44的16進制就是68,也就是D,后面不再做類似解釋)
接下來的 00 022f 31 表示target作為標(biāo)識實現(xiàn)請求和響應(yīng)的聯(lián)系,一般是自增整數(shù)。00表示數(shù)據(jù)類型為Number,02表示長度為兩個字節(jié),2f 31其實就是/1
00 0000 2d Body的長度為Number類型,長度為45
0a 0000 0003 0a表示數(shù)組類型(類似于C#中的Dictionary,鍵值對,鍵總是string類型),長度為3
數(shù)組的第一部分
0200 0ce5 a881 e8bf 85e6 9599 e882 b2 02表示字符串類型,0c表示此字符串長度為12,后面的e5 a881 e8bf 85e6 9599 e882 b2
表示傳遞的數(shù)據(jù),可以用下段代碼查看
+ expand sourceview plaincopy to clipboardprint?
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); //廣告
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); //廣告
數(shù)組的第二部分
02 0001 30 字符串0,不知道有什么意義
數(shù)組的第三部分
02 0012 3230 3130 2d36 2d31 7c32 3031 302d 362d 3131
長度為18的字符串,內(nèi)容為2010-6-1|2010-6-11
至此,請求的數(shù)據(jù)我們已經(jīng)分析完畢,再簡單說下返回的數(shù)據(jù)(Response Content)
返回的AMF Message當(dāng)然也包括Header和Body(數(shù)組類型)
Body的Target為/1/onResult
Body的Content包括
key String類型 就是我們傳進去的關(guān)鍵詞
area Number類型 0
areaName String類型 可以用上面的代碼看到內(nèi)容,就是全國
userIndexes String類型 這里都是百度指數(shù)(用戶關(guān)注度),用逗號分隔開
mediaIndexes String類型 這里都是媒體指數(shù)(媒體關(guān)注度),用逗號分隔開(由于圖中userIndexes 占位較多,所以未顯示出來,在userIndexes數(shù)據(jù)下方)
如果想得到最后一天的百度指數(shù),只要找到mediaIndexes前面最后一個逗號后跟的數(shù)字即可(當(dāng)然要排除mediaIndexes本身數(shù)據(jù)類型及長度的占位字節(jié))
新聞熱點
疑難解答
圖片精選