講故事
前幾天有點空閒時間,在 GitHub 上看一些 .Net 的開源庫,看到關於爬蟲相關的庫,於是加入了一個 QQ 群,看到裡面各位大佬討論的是爬得越好,進去越快,於是我也想做一個爬蟲相關的東西,但是爬蟲是個危險的東西,自己也不敢隨便爬別人的網頁,於是找到了一個朋友,拿他的網站來進行練習!

練習
對於 .Net 來說,爬蟲相關的庫還是蠻多的,於是我選擇了 HtmlAgilityPack 來做一個爬蟲練習!
當然什麼是爬蟲呢?
簡而言之:
爬蟲的基本流程是:下載數據(發送 HTTP 請求並獲得返回的 response)→ 解析返回的文字(可以是 text、json、html)→ 儲存解析到的數據
學習一個框架,我們肯定是從它的官方文檔開始,地址:https://html-agility-pack.net/
Html 解析器
- From File(從檔案載入 HTML 文檔)
- From String(從指定的字串載入 HTML 文檔)
- From Web(從網際網路資源獲取 HTML 文檔)
- From Browser(從 WebBrowser 獲取 HTML 文檔)
於是我選擇了 From Web 來解析我們的 HTML 文檔,程式碼如下:
var html = @"https://dotnet9.com/";
HtmlWeb web = new HtmlWeb();
var htmlDoc = web.Load(html);
既然 HTML 文檔被我們獲取到了,我們肯定就要對 HTML 內容進行解析了。
Html 選擇器
- SelectNodes()(選擇與 XPath 表達式匹配的節點列表)
- SelectSingleNode(String)(選擇與 XPath 表達式匹配的第一個 XmlNode)
打開網站,找到我們想要爬取的網站,今天我們就來爬該網站的特色專輯下的所有文章。

打開偵錯模式,我們可以看到特色專輯是一個 a 標籤,我們再來查看該標籤的上層元素是 li,li 的上層元素是 ul,那我們就可以來取得該節點。

var allNodes = htmlDoc.DocumentNode.SelectNodes("//ul[@id='starlist']//li[@class='menu']");
當然我們也可以使用 XPath 來獲取節點內容:
var singNodes = htmlDoc.DocumentNode.SelectSingleNode("/html[1]/body[1]/header[1]/div[3]/nav[1]/ul[1]/li[3]//ul[1]")
然後我們再來獲取該特色專輯下的子選單的網址,經發現,a 標籤的 href 屬性規定連結的目標地址,那我們第一步肯定是要獲取該子選單下的所有連結!

var singNodes = htmlDoc.DocumentNode.SelectSingleNode("/html[1]/body[1]/header[1]/div[3]/nav[1]/ul[1]/li[3]//ul[1]")
.ChildNodes.Where(o => o.Name == "li");
List<string> lstUrl = new List<string>();
foreach (var item in singNodes)
{
var aNodes = item.ChildNodes.Where(o => o.Name == "a").First();
string url = aNodes.Attributes["href"].Value;
lstUrl.Add(url);
}
隨意打開一個子選單,可以看到相關的文章標題、描述以及圖片等!這就是我們想要的內容了!分析方法還是和剛才一樣!程式碼如下:

foreach (var item in lstUrl)
{
htmlDoc = web.Load("https://dotnet9.com" + item);
var resultNodes = htmlDoc.DocumentNode.SelectSingleNode("//div[@class='pics-list-box whitebg']//ul")
.ChildNodes.Where(o => o.Name == "li");
foreach (var itemResultNodes in resultNodes)
{
WebData webData = new WebData();
var aNodes = itemResultNodes.ChildNodes.Where(o => o.Name == "a").First();
webData.Url = aNodes.Attributes["href"].Value;
webData.Title = aNodes.ChildNodes["h2"].InnerText;
webData.Desc = aNodes.ChildNodes["p"].InnerText;
webData.Img = aNodes.ChildNodes["i"].ChildNodes["img"].Attributes["src"].Value;
Console.WriteLine($"標題:{webData.Title}-描述:{webData.Desc}-Img:{webData.Img}-{webData.Url}\r\n");
}
}
這樣我們就能夠獲取到我們想要的東西了!執行程式碼,我們的第一個爬蟲就成功了。

總結
即興發揮寫了第一個爬蟲,大家要是有更好的方案,歡迎交流,獨樂樂不如眾樂樂,本篇就到這裡為止,希望對您有幫助。
最後聲明一下:總的來說,技術本無罪,但是你利用技術爬取別人隱私、商業數據,那你就蔑視法律了,請各位守好各自的底線!