想弄一個數據庫,因爲須要一些人名,因此就去百度一下,而後發現了360圖書館中有不少人名html
而後就像去複製一下,發現複製不了,須要登錄正則表達式
此時f12查看源碼是能夠複製的,不過就算能夠複製想要插入數據也是很麻煩的。既然複製走不通,因而我抱着探索知識的精神,打開了Visual Studio數據庫
public static void GetData(String address) { WebClient wc = new WebClient(); byte[] htmlData = wc.DownloadData(address); }
此時須要將htmlData對象解碼爲String對象,而後咱們在網站中f12看一下解碼方式編程
能夠看到charset=utf-8,說明須要用utf-8來解碼,而後使用Encoding對象來解碼數組
string html = Encoding.UTF8.GetString(htmlData);
咱們輸出一下html有沒有值學習
static void Main(string[] args) { //將地址複製過來 GetData("http://www.360doc.com/content/18/1010/13/642066_793541226.shtml"); Console.ReadKey(); } public static void GetData(String address) { WebClient wc = new WebClient(); //地址由調用時傳入 byte[] htmlData = wc.DownloadData(address); string html = Encoding.UTF8.GetString(htmlData); Console.WriteLine(html); }
輸出:網站
接下來就是匹配的問題了,首先看一下html文檔的結構url
就是說只須要匹配到全部的p標籤,而後拿到其中的內容就好了spa
第一種想到的就是使用正則表達式匹配:code
public static void GetData(String address) { WebClient wc = new WebClient(); //地址由調用時傳入 byte[] htmlData = wc.DownloadData(address); string html = Encoding.UTF8.GetString(htmlData); //使用正則表達式匹配 <p或P>非空字符至少100個<P或p> Regex reg = new Regex("<[pP]>\\S{100,}</[Pp]>"); //接受全部匹配到的項 MatchCollection result = reg.Matches(html); //循環輸出 foreach (Match item in result) { Console.WriteLine(item.Value); } }
調用不變,啓動:
匹配到是匹配到了,可是咱們把<p></p>標籤也匹配出來了,因此把正則表達式改進一下,使用組匹配,將p標籤中的內容單獨匹配出來(固然也能夠截取字符串)。也就是說在寫正則表達式時,將想要單獨匹配出來的數據用括號"(想要單獨匹配出來的數據)"括起來,來看一下怎麼寫:
Regex reg = new Regex("<[pP]>(\\S{100,})</[Pp]>");
而後若是想要拿數據的話,須要使用Match對象的Groups屬性經過索引來獲取匹配到的組:
public static void GetData(String address) { WebClient wc = new WebClient(); //地址由調用時傳入 byte[] htmlData = wc.DownloadData(address); string html = Encoding.UTF8.GetString(htmlData); //使用正則表達式組匹配 <p或P>(非空字符至少100個)<P或p> Regex reg = new Regex("<[pP]>(\\S{100,})</[Pp]>"); //接受全部匹配到的項 MatchCollection result = reg.Matches(html); //循環輸出 foreach (Match item in result) { //0的話是總體匹配到的字符串對象 //1就是第一個匹配到的組(\\S{100,) Console.WriteLine(item.Groups[1]); } }
輸出結果:
此次p標籤就沒有被匹配進入組中(若是經過item.Groups[0]拿到的回是和上面匹配到同樣的數據,會帶p標籤)
匹配到了以後就可使用item.Groups[1].Split('、')來將字符串分割爲String數組,而後循環寫入數據庫,或者進行其餘操做。
雖然正則表達式也能夠匹配,可是若是對正則表達式比較陌生的話,可能就不是友好了。若是有方法能夠像用js操做html元素同樣,用C#操做html字符串,就很是棒了。NSoup就是能夠作到解析html字符串,變成可操做的對象。
首先使用前先在管理NuGet程序包中添加:NSoup,直接就能夠搜索到,添加完成以後接下來就看一下如何使用
使用NSoupClient.Parse(放入html代碼:<html>....</html>)建立一個聲明Docuemnt文檔對象:
//聲明Document對象 Document doc = NSoupClient.Parse(html);
第二種就是使用Document doc = NSoupClient.Connect(放入url) .Get()/.Post(),而後他就會自動獲取url地址的html代碼,而且根據html代碼加載一個Document對象
//經過url自動加載Document對象 Document doc = NSoupClient.Connect(address).Get();
固然還有其餘方式獲取,而後咱們看一下如何使用Document對象
//經過id獲取元素 //獲取id爲form的元素 Element form = doc.GetElementById("form"); //經過標籤名獲取元素 //獲取全部的p標籤 Elements p = doc.GetElementsByTag("p"); //經過類樣式獲取元素 //獲取類樣式爲btn的元素 Elements c = doc.GetElementsByClass("btn"); //經過屬性獲取 //獲取包含style屬性的元素 Elements attr = doc.GetElementsByAttribute("style");
也能夠本身組合一些其餘的嵌套操做,例如:
獲取id爲artContent下的全部p標籤
//使用鏈式編程 //獲取id爲artContent下的全部p標籤 Elements ps = doc.GetElementById("artContent").GetElementsByTag("p"); //等同於 //Element artContent = doc.GetElementById("artContent"); //Elements ps = artContent.GetElementsByTag("p");
元素方法的使用:
//Elements是Element元素的集合 多了個s //Element對象的方法 Element id = doc.GetElementById("id"); //獲取或設置id元素的文本 id.Text(); //獲取或設置id元素的html代碼 id.Html(); //獲取或設置id元素的value值 id.Val();
都是像js操做html元素同樣的方法,並且方法的名字也很人性,基本上一看就會知道方法是什麼意思,方法也太多了就不一一講了。
而後咱們來使用NSoup獲取全部的名字,來試一下就會發現很簡單了:
方式一:
public static void GetData(String address) { WebClient wc = new WebClient(); byte[] htmlData = wc.DownloadData(address); string html = Encoding.UTF8.GetString(htmlData); Document doc = NSoupClient.Parse(html); //先獲取id爲artContent的元素,再獲取全部的p標籤 Elements p = doc.GetElementById("artContent").GetElementsByTag("p"); foreach (Element item in p) { Console.WriteLine(item.Text()); } }
方式二:
public static void GetData(String address) { //直接經過url來獲取Document對象 Document doc = NSoupClient.Connect(address).Get(); //先獲取id爲artContent的元素,再獲取全部的p標籤 Elements p = doc.GetElementById("artContent").GetElementsByTag("p"); foreach (Element item in p) { Console.WriteLine(item.Text()); } }
運行結果都是同樣的