在進行網頁自動化時我們做得最多的工作就是不停的往某個URL GET/POST數據並得到相應的Response,通過分析Response的結果再進行下一步操作,通過網頁自動化我們可以做很多工作,比如去某個網站抓取我們想要的數據,批量注冊,模擬人工操作網頁,批量提交,去年12306網上訂火車票的系統出來后相繼開發出來的各種搶票工具就是這一網頁自動化應用的最好注腳。非常幸運的是,.NET C#提供了強大的函數庫可以輕易的完成這一作,但是現在我要發布的AliasNet將把這一工作變得更為簡單。有我簡單?一句話就OK。
總的來說:AliasNet,提供一種簡單,方便,封裝,統一的GET/POST方法。
1. AliasNet的基本使用
string response=new GetAndPostHelper().GETString("http://www.baidu.com") ;
OK,response里保存的就將是百度首頁的HTML內容。
2. AliasNet的高級使用
GETAndPostHelper() helper= new GetAndPostHelper( true); // 初始化HTTPS的GETAndPostHelper
helper.SetCookies(CookieContainer cookies); // 設置本次連接的Cookie
helper.SetCredential(userName,password); // 設置本次連接的認證信息(這在內部網站里很有用)
helper.SetProxy(proxyIP,proxyPort); // 設置本次連接的代理
helper.GETBytes(url); // GET數據,返回byte[]
helper.POSTString(url,parameter); // POST數據,返回string
helper.POSTBytes(url,paremeter); // POST數據,返回byte[]
helper.DownloadFile(url,fileName); // 將url內容保存為本地文件,這對下載圖片網頁等很有用
GET數據時,參數就連到URL里面作為QueryString傳遞到服務器,但是當POST數據時,我們需要顯式的傳遞一個參數parameter,它是類Parameter的實體,其中類Parameter定義如下:
/// <summary>
/// Parameter類,繼承自 Dictionary <string, string>/// 以Key-Value的形式保存GET/POST的數
/// </summary>
public class Parameters : Dictionary< string, string>
{
/// <summary>
/// 重寫ToString方法,以QueryString的方式連接各值
/// </summary>
/// <returns></returns>
public override string ToString()
{
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair< string, string> pair in this)
{
sb.Append( string.Format( " {0}={1}& ", pair.Key, pair.Value));
}
if (sb.Length > 0)
sb.Remove(sb.Length - 1, 1);
return sb.ToString();
}
}
可以看到Parameter就是一個string-string的字典,我們把需要POST的數據放到里面去就OK了。
3.GET/POST 響應數據的處理辦法
一般來說我們GET/POST數據無非是兩種需求,一是下載相應的文件(可以用helper.DownloadFile)實現 ,二是獲取返回結果提取數據(可以用helper.GETString(POSTStrin))實現。現重點說說后者。
根據服務器的返回結果,我們可以把他們為以下三類:
(1)HTML
處理HTML字符串當然首推HtmlAgilityPack.dll 了,可以用HTMLDocumnet載入 HTML字符串,再用XPath搜索想要的節點,最后用HTMLNode的innerText,innerHTML,GetAttribute 等方法就可以很方便的得到數據。
(2)JSON
處理JSOn數據我最喜歡使用Newtonsoft.Json 來實例化一個實體類,然后操作類來實現。AliasNet提供了JsonClassBase基類來處理JSON數據,一般來說,分析JSON數據的結構並寫出現應的.NET實體類,並讓之繼承自JsonClassBase基類,使用調用 JsonClassBase.FromJson<T>(string json)方法就可以把JSON數據輕易的轉換為.NET實體類了。
(3)包括XML等的其它
4.實例:利用AliasNet從無憂代理上獲取最新的代理
無憂代理是我喜歡上的幾個代理網上,每隔幾小時它都會更新當前最新最好用的代理IP和端口,所以我們可以用AliasNet來自動抓取代理信息。
下面的例子將會抓取http://www.51proxied.com/http_anonymous.html 即無憂代理的匿名HTTP代理
/// 從無憂代理網站得到當前最新的代理
/// </summary>
/// <param name="proxyUrl"> 代理Web URL </param>
/// <param name="regionFilter"> 過濾指定的region,不過濾使用""或null </param>
/// <returns> 代理命令 </returns>
public static List<Proxy> _51proxied_HttpProxy( string proxyUrl, string regionFilter)
{
string resultString = new GetAndPostHelper().GETString(proxyUrl);
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(resultString);
HtmlNode divNode = doc.GetElementbyId( " tb ");
HtmlNodeCollection tdNodesCollection = divNode.SelectNodes( " //div/table//td ");
List<HtmlNode> tdNodes = new List<HtmlNode>();
foreach (HtmlNode node in tdNodesCollection)
tdNodes.Add(node);
List<Proxy> proxy = new List<Proxy>();
for ( int i = 0; i < tdNodes.Count / 4; i++)
{
string region = tdNodes[i * 4 + 3].InnerText.Trim();
if ( string.IsNullOrEmpty(regionFilter) || region == regionFilter)
{
Proxy p = new Proxy();
p.IP = tdNodes[i * 4 + 1].InnerText.Trim(); ;
p.Port = int.Parse(tdNodes[i * 4 + 2].InnerText.Trim());
p.Region = region;
proxy.Add(p);
}
}
return proxy; }
這個方法我也封裝成了ProxyFinder放到了AliasNet里面,一方面可以做為AliasNet使用的一個例子,一方面也算是額外的福利吧,反正我抓代理用得也蠻多的。
總結:
AliasNet現已托管到GitHub上並全面開源,感興趣的可以訪問:https://github.com/superliujian/AliasNet 或者聯系我:liu_jian_china@qq.com
另外預告一下:簡單自適應的輕量級數據庫訪問庫AliasDB也已經開源,近期將公布。 AliasDB使得用戶只需要提供一個連接字符串就可以運用統一的訪問訪問MySQL/SQLServer/Oracle/SQLite以及通過支持ODBC/OleDb 的所有數據庫(比如Access), 而且,當你的數據庫結構變化時,比如字段增刪等,該訪問仍然有效,不用再做任意的ORM,或者 自己寫SQL語句或者 自己編寫數據庫實體。這在中小型系統中十分有用。