C# 基於 .Net-HtmlAgilityPack 庫的爬蟲初體驗

C# 基於 .Net-HtmlAgilityPack 庫的爬蟲初體驗

在 GitHub 上看一些 .Net 的開源庫,看到了關於爬蟲相關的庫

最後更新 2022/6/9 下午10:54
黑哥聊dotNet
預計閱讀 4 分鐘
分類
.NET
標籤
.NET C# 開源 GitHub

講故事

前幾天有點空閒時間,在 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 標籤,我們再來查看該標籤的上層元素是 lili 的上層元素是 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");
    }
}

這樣我們就能夠獲取到我們想要的東西了!執行程式碼,我們的第一個爬蟲就成功了。

總結

即興發揮寫了第一個爬蟲,大家要是有更好的方案,歡迎交流,獨樂樂不如眾樂樂,本篇就到這裡為止,希望對您有幫助。

最後聲明一下:總的來說,技術本無罪,但是你利用技術爬取別人隱私、商業數據,那你就蔑視法律了,請各位守好各自的底線!

繼續探索

延伸閱讀

更多文章