曾經做網站類型的程序時,經常需要收集客戶端的訪問數據,然后加以分析。這需要一個Ip數據庫,數據表中顯示Ip所在的省份市區等信息。網絡上有流傳的Ip純真數據庫,一些公開的Web服務也可以查詢Ip地址信息,但是24小時內超過查詢次數就需要購買商業授權,網站myds.net上提供了Ip數據庫下載,不過需要收取60元人民幣。
最后一種方法,也就是不花錢的辦法,用C#調用淘寶的Ip地址庫,准確率高,而且查詢次數不限制。
先參考網方提供的文檔:
淘寶IP地址庫,提供API
提供的服務包括:
1. 根據用戶提供的IP地址,快速查詢出該IP地址所在的地理信息和地理相關的信息,包括國家、省、市和運營商。
2. 用戶可以根據自己所在的位置和使用的IP地址更新我們的服務內容。
優勢:
1. 提供國家、省、市、縣、運營商全方位信息,信息維度廣,格式規范。
2. 提供完善的統計分析報表,省准確度超過99.8%,市准確度超過96.8%,數據質量有保障。
接口說明
1. 請求接口(GET):
http://ip.taobao.com/service/getIpInfo.php?ip=[ip地址字串]
2. 響應信息:
(json格式的)國家 、省(自治區或直轄市)、市(縣)、運營商
3. 返回數據格式:
{"code":0,"data":{"ip":"210.75.225.254","country":"\u4e2d\u56fd","area":"\u534e\u5317",
"region":"\u5317\u4eac\u5e02","city":"\u5317\u4eac\u5e02","county":"","isp":"\u7535\u4fe1",
"country_id":"86","area_id":"100000","region_id":"110000","city_id":"110000",
"county_id":"-1","isp_id":"100017"}}
其中code的值的含義為,0:成功,1:失敗。
步驟1 : 找到枚舉互聯網Ip地址的方法
StackOverflow上面有一篇文章,講解如何枚舉所有的互聯網Ip地址。請參考 C# Enumerate IP addresses in a range - Stack Overflow
請看下面的Ip地址參數例子
'192.0.2.1' 一個Ip地址
'192.0.2.0-31' 枚舉192.0.2.0-192.0.2.31 一共32個Ip地址
'192.0.2-3.1-254' 枚舉192.0.2.1-192.0.2.254和 192.0.3.1-192.0.3.254 一共254個IP地址
'0-255.0-255.0-255.0-255' 枚舉互聯網上所有的IPv4地址
代碼中的調用方法
string pattern="200.64-71.0-255.0-255"; IPRange ipRange=new IPRange(pattern); List<IPAddress> addresses=ipRange.GetAllIP();
這樣,就得到了所有的Ip地址。
步驟2:依此發送Web請求,得到Json返回值
參考下面的代碼,得到每個Ip地址的查詢結果
WebRequest request = HttpWebRequest.Create("http://ip.taobao.com/service/getIpInfo.php?ip-200.9.210.200"); request.Credentials = CredentialCache.DefaultCredentials; HttpWebResponse response = (HttpWebResponse) request.GetResponse(); Stream dataStream = response.GetResponseStream(); StreamReader reader = new StreamReader(dataStream); string responseFromServer = reader.ReadToEnd(); reader.Close(); dataStream.Close(); response.Close();
這里為了提高性能,可以用多線程,也可以並行方法,如下面的代碼例子
Parallel.ForEach(addresses, (address)=> { …… });
3 解析請求的Json結果,生成DataTable
把Json變成.NET Object有幾種方法。著名的JSON.NET自然很容易就實現,但是不我想依賴第三方的庫,.NET內置的JavaScriptSerializer可以實現這個目的。
JavaScriptSerializer serializer=new JavaScriptSerializer(); object obj=serializer.Deserialize<object>(json); Dictionary<string,object> ip=obj as Dictionary<string,object>
Json解析的結果,是二個Dictionary,第一個默認是0,我取第二個字典項的Value的值,它是一個字符串Array
於是,根據這個字符串數組,生成表的列。
4 合並所有Ip地址的DataTable數據到一個DataTable中,並把它寫到Access數據庫中
先創建一個結果表,用於存放每個Ip地址采集的數據
DataTable final=new DataTable() ...json => DataTable table; if(final.Columns.Count==0) final=table.Clone(); final.Merge(table);
再創建一個AccessHelper類型,可以直接寫數據到文件中。
AccessHelper access=new AccessHelper(@"C:\Data\Ip.accdb"); access.AppendData(final);
它會根據DataTable的結構,自動生成創建Access表結構的SQL語句,再把DataTable中的數據以參數的方式插入到
數據表中。 這里應該注意,不應該用Microsoft.Jet.Oledb4.0,Jet很早就停止開發,並且不能在x64的電腦中運行。一種辦法是要將Target設成x86,或是使用Access Runtime 2007,它提供了Microsft.Ace.12.0,這個新的驅動程序,可以運行於x64系統中,並且支持新的accdb格式的數據庫。