How to Scrape Data from Websites in C

This article was translated from English: Does it need improvement?
Translated
View the article in English

IronWebScraper 是一個用於網頁抓取、網頁資料擷取及網頁內容解析的 .NET 程式庫。 這是一個易於使用的函式庫,可加入 Microsoft Visual Studio 專案中,用於開發與生產環境。

IronWebscraper 具備眾多獨特功能與能力,例如控制允許與禁止的頁面、物件、媒體等。它還支援多重身分管理、網頁快取,以及許多其他功能,我們將在本教學中詳細介紹。

開始使用 IronWebScraper

立即透過免費試用,在您的專案中開始使用 IronWebScraper。

第一步:
green arrow pointer


目標受眾

本教學指南針對具備基礎或進階程式設計技能的軟體開發人員,旨在協助其建構並實作具備進階擷取功能的解決方案(包含網站擷取、網站資料蒐集與提取、網站內容解析及網頁收穫)。

網頁抓取圖片

所需技能

  1. 具備程式設計基礎知識,並精通一種 Microsoft 程式語言(例如 C# 或 VB.NET)
  2. 具備網頁技術(HTML、JavaScript、jQuery、CSS 等)及其運作原理的基本理解
  3. 具備 DOM、XPath、HTML 及 CSS 選擇器的基礎知識

工具

  1. Microsoft Visual Studio 2010 或更高版本
  2. 瀏覽器專用的網頁開發者擴充功能,例如 Chrome 的 Web Inspector 或 Firefox 的 Firebug

為何要進行網頁抓取? (Reasons and Concepts)

如果您希望打造具備以下功能的產品或解決方案:

  1. 擷取網站資料
  2. 比較多個網站的內容、價格、功能等
  3. 掃描與快取網站內容

若您符合上述任一或多項條件,IronWebScraper 將是滿足您需求的絕佳程式庫

如何安裝 IronWebScraper?

完成 Create a New Project(參見附錄 A)後,您可以透過 NuGet 自動加入 IronWebScraper 函式庫,或手動安裝 DLL 檔案。

使用 NuGet 安裝

若要透過 NuGet 將 IronWebScraper 函式庫新增至我們的專案,我們可以使用視覺化介面(NuGet 套件管理員),或透過命令列使用套件管理員控制台來執行。

使用 NuGet 套件管理員

  1. 使用滑鼠 -> 右鍵點擊專案名稱 -> 選擇"管理 NuGet 套件"
  2. 從"瀏覽"分頁 -> 搜尋 IronWebScraper -> 安裝
  3. 點擊"確定"
  4. 完成

使用 NuGet 套件控制台

  1. 從"工具"→"NuGet 套件管理員"→"套件管理員主控台"
  2. 選擇"類別庫專案"作為預設專案
  3. 執行命令 -> Install-Package IronWebScraper

手動安裝

  1. 前往 </https:>
  2. 點擊 IronWebscraper 或直接透過網址造訪其頁面 https://ironsoftware.com/csharp/webscraper/
  3. 點擊"下載 DLL"。
  4. 解壓縮下載的壓縮檔
  5. 在 Visual Studio 中,右鍵點擊專案 -> 新增 -> 參考項 -> 瀏覽

    使用 DLL 加入 IronWebscraper

  6. 前往解壓縮後的資料夾 -> netstandard2.0 -> 並選取所有 .dll 檔案

    透過 DLL 2 加入 IronWebscraper

  7. 完成!

HelloScraper - 我們的第一個 IronWebscraper 範例

一如往常,我們將從實作"Hello Scraper App"開始,以此作為使用 IronWebScraper 的第一步。

  • 我們已建立一個名為"IronWebScraperSample"的新主控台應用程式

建立 IronWebscraper 範例的步驟

  1. 建立一個資料夾並將其命名為"HelloScraperSample"
  2. 接著新增一個類別,並將其命名為 HelloScraper HelloScraper 新增類別

  3. 將此程式碼片段加入 HelloScraper

    public class HelloScraper : WebScraper
    {
        /// <summary>
        /// Override this method to initialize your web scraper.
        /// Important tasks will be to request at least one start URL and set allowed/banned domain or URL patterns.
        /// </summary>
        public override void Init()
        {
            License.LicenseKey = "LicenseKey"; // Write License Key
            this.LoggingLevel = WebScraper.LogLevel.All; // Log all events
            this.Request("https://blog.scrapinghub.com", Parse); // Initialize a web request to the given URL
        }
    
        /// <summary>
        /// Override this method to create the default Response handler for your web scraper.
        /// If you have multiple page types, you can add additional similar methods.
        /// </summary>
        /// <param name="response">The HTTP Response object to parse</param>
        public override void Parse(Response response)
        {
            // Set working directory for the project
            this.WorkingDirectory = AppSetting.GetAppRoot() + @"\HelloScraperSample\Output\";
            // Loop on all links
            foreach (var titleLink in response.Css("h2.entry-title a"))
            {
                // Read link text
                string title = titleLink.TextContentClean;
                // Save result to file
                Scrape(new ScrapedData() { { "Title", title } }, "HelloScraper.json");
            }
    
            // Loop on all links for pagination
            if (response.CssExists("div.prev-post > a[href]"))
            {
                // Get next page URL
                var nextPage = response.Css("div.prev-post > a[href]")[0].Attributes["href"];
                // Scrape next URL
                this.Request(nextPage, Parse);
            }
        }
    }
    public class HelloScraper : WebScraper
    {
        /// <summary>
        /// Override this method to initialize your web scraper.
        /// Important tasks will be to request at least one start URL and set allowed/banned domain or URL patterns.
        /// </summary>
        public override void Init()
        {
            License.LicenseKey = "LicenseKey"; // Write License Key
            this.LoggingLevel = WebScraper.LogLevel.All; // Log all events
            this.Request("https://blog.scrapinghub.com", Parse); // Initialize a web request to the given URL
        }
    
        /// <summary>
        /// Override this method to create the default Response handler for your web scraper.
        /// If you have multiple page types, you can add additional similar methods.
        /// </summary>
        /// <param name="response">The HTTP Response object to parse</param>
        public override void Parse(Response response)
        {
            // Set working directory for the project
            this.WorkingDirectory = AppSetting.GetAppRoot() + @"\HelloScraperSample\Output\";
            // Loop on all links
            foreach (var titleLink in response.Css("h2.entry-title a"))
            {
                // Read link text
                string title = titleLink.TextContentClean;
                // Save result to file
                Scrape(new ScrapedData() { { "Title", title } }, "HelloScraper.json");
            }
    
            // Loop on all links for pagination
            if (response.CssExists("div.prev-post > a[href]"))
            {
                // Get next page URL
                var nextPage = response.Css("div.prev-post > a[href]")[0].Attributes["href"];
                // Scrape next URL
                this.Request(nextPage, Parse);
            }
        }
    }
    Public Class HelloScraper
    	Inherits WebScraper
    
    	''' <summary>
    	''' Override this method to initialize your web scraper.
    	''' Important tasks will be to request at least one start URL and set allowed/banned domain or URL patterns.
    	''' </summary>
    	Public Overrides Sub Init()
    		License.LicenseKey = "LicenseKey" ' Write License Key
    		Me.LoggingLevel = WebScraper.LogLevel.All ' Log all events
    		Me.Request("https://blog.scrapinghub.com", AddressOf Parse) ' Initialize a web request to the given URL
    	End Sub
    
    	''' <summary>
    	''' Override this method to create the default Response handler for your web scraper.
    	''' If you have multiple page types, you can add additional similar methods.
    	''' </summary>
    	''' <param name="response">The HTTP Response object to parse</param>
    	Public Overrides Sub Parse(ByVal response As Response)
    		' Set working directory for the project
    		Me.WorkingDirectory = AppSetting.GetAppRoot() & "\HelloScraperSample\Output\"
    		' Loop on all links
    		For Each titleLink In response.Css("h2.entry-title a")
    			' Read link text
    			Dim title As String = titleLink.TextContentClean
    			' Save result to file
    			Scrape(New ScrapedData() From {
    				{ "Title", title }
    			},
    			"HelloScraper.json")
    		Next titleLink
    
    		' Loop on all links for pagination
    		If response.CssExists("div.prev-post > a[href]") Then
    			' Get next page URL
    			Dim nextPage = response.Css("div.prev-post > a[href]")(0).Attributes("href")
    			' Scrape next URL
    			Me.Request(nextPage, AddressOf Parse)
    		End If
    	End Sub
    End Class
    $vbLabelText   $csharpLabel
  4. 現在要開始進行抓取,請將此程式碼片段加入 Main

    static void Main(string[] args)
    {
        // Create Object From Hello Scrape class
        HelloScraperSample.HelloScraper scrape = new HelloScraperSample.HelloScraper();
        // Start Scraping
        scrape.Start();
    }
    static void Main(string[] args)
    {
        // Create Object From Hello Scrape class
        HelloScraperSample.HelloScraper scrape = new HelloScraperSample.HelloScraper();
        // Start Scraping
        scrape.Start();
    }
    Shared Sub Main(ByVal args() As String)
    	' Create Object From Hello Scrape class
    	Dim scrape As New HelloScraperSample.HelloScraper()
    	' Start Scraping
    	scrape.Start()
    End Sub
    $vbLabelText   $csharpLabel
  5. 翻譯結果將儲存於格式為 WebScraper.WorkingDirectory/classname.Json 的檔案中 HelloScraper 結果

程式碼概覽

Scrape.Start() 會以以下方式觸發擷取邏輯:

  1. 呼叫 Init() 方法以初始化變數、擷取屬性及行為屬性。
  2. 使用 Request("https://blog.scrapinghub.com", Parse) 設定 Init() 中的起始頁面請求。
  3. 能並行處理多個 HTTP 請求與執行緒,使程式碼保持同步並更易於除錯。
  4. Parse() 方法會在 Init() 之後觸發,以處理回應,透過 CSS 選擇器擷取資料,並將其儲存為 JSON 格式。

IronWebscraper程式庫的功能與選項

https://ironsoftware.com/csharp/webscraper/object-reference/更新後的文件可於透過手動安裝方式下載的 ZIP 檔案中找到(IronWebScraper Documentation.chm File),您亦可前往 查閱該函式庫的線上文件以獲取最新更新資訊。

若要在您的專案中開始使用 IronWebScraper,您必須繼承 IronWebScraper.WebScraper 類別,該類別將擴展您的類別庫並為其增添擷取功能。 此外,您必須實作 Init()Parse(Response response) 方法。

namespace IronWebScraperEngine
{
    public class NewsScraper : IronWebScraper.WebScraper
    {
        public override void Init()
        {
            throw new NotImplementedException();
        }

        public override void Parse(Response response)
        {
            throw new NotImplementedException();
        }
    }
}
namespace IronWebScraperEngine
{
    public class NewsScraper : IronWebScraper.WebScraper
    {
        public override void Init()
        {
            throw new NotImplementedException();
        }

        public override void Parse(Response response)
        {
            throw new NotImplementedException();
        }
    }
}
Namespace IronWebScraperEngine
	Public Class NewsScraper
		Inherits IronWebScraper.WebScraper

		Public Overrides Sub Init()
			Throw New NotImplementedException()
		End Sub

		Public Overrides Sub Parse(ByVal response As Response)
			Throw New NotImplementedException()
		End Sub
	End Class
End Namespace
$vbLabelText   $csharpLabel
屬性 \ 功能 類型 描述
Init () 方法 用於設定擷取工具
Parse (Response response) 方法 用於實作擷取工具將使用的邏輯及其處理方式。 可針對不同的頁面行為或結構實作多種方法。
BannedUrls, AllowedUrls, BannedDomains 系列 用於封鎖/允許特定網址和/或網域。 例:BannedUrls.Add("*.zip", "*.exe", "*.gz", "*.pdf"); 支援萬用字元與正規表達式。
ObeyRobotsDotTxt 布林 用於啟用或停用 robots.txt 中的指令之讀取與執行。
ObeyRobotsDotTxtForHost (string Host) 方法 用於啟用或停用針對特定網域讀取並遵循 robots.txt 中的指令。
Scrape, ScrapeUnique 方法
ThrottleMode 枚舉 枚舉選項:ByDomainHostName。 支援智慧型請求限流,並能依據主機 IP 位址或網域名稱進行調整。
EnableWebCache, EnableWebCache (TimeSpan cacheDuration) 方法 啟用網頁請求的快取功能。
MaxHttpConnectionLimit Int 設定允許開啟的 HTTP 請求(執行緒)總數。
RateLimitPerHost TimeSpan 設定針對特定網域或 IP 位址發送請求之間的最小禮貌延遲(暫停時間)。
OpenConnectionLimitPerHost Int 設定每個主機名稱或 IP 位址允許的並發 HTTP 請求(執行緒)數量。
WorkingDirectory string 設定用於儲存資料的工作目錄路徑。

實際案例與實作練習

抓取線上電影網站

讓我們建立一個範例,來抓取電影網站的資料。

新增一個類別並將其命名為 MovieScraper

新增 MovieScraper 類別

HTML 結構

以下是網站首頁 HTML 中的部分內容:

<div id="movie-featured" class="movies-list movies-list-full tab-pane in fade active">
    <div data-movie-id="20746" class="ml-item">
        <a href="https://website.com/film/king-arthur-legend-of-the-sword-20746/">
            <span class="mli-quality">CAM</span>
            <img data-original="https://img.gocdn.online/2017/05/16/poster/2116d6719c710eabe83b377463230fbe-king-arthur-legend-of-the-sword.jpg" 
                 class="lazy thumb mli-thumb" alt="King Arthur: Legend of the Sword"
                  src="https://img.gocdn.online/2017/05/16/poster/2116d6719c710eabe83b377463230fbe-king-arthur-legend-of-the-sword.jpg" 
                 style="display: inline-block;">
            <span class="mli-info"><h2>King Arthur: Legend of the Sword</h2></span>
        </a>
    </div>
    <div data-movie-id="20724" class="ml-item">
        <a href="https://website.com/film/snatched-20724/" >
            <span class="mli-quality">CAM</span>
            <img data-original="https://img.gocdn.online/2017/05/16/poster/5ef66403dc331009bdb5aa37cfe819ba-snatched.jpg" 
                 class="lazy thumb mli-thumb" alt="Snatched" 
                 src="https://img.gocdn.online/2017/05/16/poster/5ef66403dc331009bdb5aa37cfe819ba-snatched.jpg" 
                 style="display: inline-block;">
            <span class="mli-info"><h2>Snatched</h2></span>
        </a>
    </div>
</div>
<div id="movie-featured" class="movies-list movies-list-full tab-pane in fade active">
    <div data-movie-id="20746" class="ml-item">
        <a href="https://website.com/film/king-arthur-legend-of-the-sword-20746/">
            <span class="mli-quality">CAM</span>
            <img data-original="https://img.gocdn.online/2017/05/16/poster/2116d6719c710eabe83b377463230fbe-king-arthur-legend-of-the-sword.jpg" 
                 class="lazy thumb mli-thumb" alt="King Arthur: Legend of the Sword"
                  src="https://img.gocdn.online/2017/05/16/poster/2116d6719c710eabe83b377463230fbe-king-arthur-legend-of-the-sword.jpg" 
                 style="display: inline-block;">
            <span class="mli-info"><h2>King Arthur: Legend of the Sword</h2></span>
        </a>
    </div>
    <div data-movie-id="20724" class="ml-item">
        <a href="https://website.com/film/snatched-20724/" >
            <span class="mli-quality">CAM</span>
            <img data-original="https://img.gocdn.online/2017/05/16/poster/5ef66403dc331009bdb5aa37cfe819ba-snatched.jpg" 
                 class="lazy thumb mli-thumb" alt="Snatched" 
                 src="https://img.gocdn.online/2017/05/16/poster/5ef66403dc331009bdb5aa37cfe819ba-snatched.jpg" 
                 style="display: inline-block;">
            <span class="mli-info"><h2>Snatched</h2></span>
        </a>
    </div>
</div>
HTML

如我們所見,這裡包含電影 ID、標題以及詳細頁面連結。 讓我們開始抓取這些資料:

public class MovieScraper : WebScraper
{
    public override void Init()
    {
        License.LicenseKey = "LicenseKey";
        this.LoggingLevel = WebScraper.LogLevel.All;
        this.WorkingDirectory = AppSetting.GetAppRoot() + @"\MovieSample\Output\";
        this.Request("www.website.com", Parse);
    }

    public override void Parse(Response response)
    {
        foreach (var div in response.Css("#movie-featured > div"))
        {
            if (div.GetAttribute("class") != "clearfix")
            {
                var movieId = div.GetAttribute("data-movie-id");
                var link = div.Css("a")[0];
                var movieTitle = link.TextContentClean;
                Scrape(new ScrapedData() { { "MovieId", movieId }, { "MovieTitle", movieTitle } }, "Movie.Jsonl");
            }
        }           
    }
}
public class MovieScraper : WebScraper
{
    public override void Init()
    {
        License.LicenseKey = "LicenseKey";
        this.LoggingLevel = WebScraper.LogLevel.All;
        this.WorkingDirectory = AppSetting.GetAppRoot() + @"\MovieSample\Output\";
        this.Request("www.website.com", Parse);
    }

    public override void Parse(Response response)
    {
        foreach (var div in response.Css("#movie-featured > div"))
        {
            if (div.GetAttribute("class") != "clearfix")
            {
                var movieId = div.GetAttribute("data-movie-id");
                var link = div.Css("a")[0];
                var movieTitle = link.TextContentClean;
                Scrape(new ScrapedData() { { "MovieId", movieId }, { "MovieTitle", movieTitle } }, "Movie.Jsonl");
            }
        }           
    }
}
Public Class MovieScraper
	Inherits WebScraper

	Public Overrides Sub Init()
		License.LicenseKey = "LicenseKey"
		Me.LoggingLevel = WebScraper.LogLevel.All
		Me.WorkingDirectory = AppSetting.GetAppRoot() & "\MovieSample\Output\"
		Me.Request("www.website.com", AddressOf Parse)
	End Sub

	Public Overrides Sub Parse(ByVal response As Response)
		For Each div In response.Css("#movie-featured > div")
			If div.GetAttribute("class") <> "clearfix" Then
				Dim movieId = div.GetAttribute("data-movie-id")
				Dim link = div.Css("a")(0)
				Dim movieTitle = link.TextContentClean
				Scrape(New ScrapedData() From {
					{ "MovieId", movieId },
					{ "MovieTitle", movieTitle }
				},
				"Movie.Jsonl")
			End If
		Next div
	End Sub
End Class
$vbLabelText   $csharpLabel

結構化 Movie 類別

為了存放格式化的資料,讓我們實作一個電影類別:

public class Movie
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string URL { get; set; }
}
public class Movie
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string URL { get; set; }
}
Public Class Movie
    Public Property Id As Integer
    Public Property Title As String
    Public Property URL As String
End Class
$vbLabelText   $csharpLabel

現在請更新我們的程式碼,以使用 Movie 類別:

public class MovieScraper : WebScraper
{
    public override void Init()
    {
        License.LicenseKey = "LicenseKey";
        this.LoggingLevel = WebScraper.LogLevel.All;
        this.WorkingDirectory = AppSetting.GetAppRoot() + @"\MovieSample\Output\";
        this.Request("https://website.com/", Parse);
    }

    public override void Parse(Response response)
    {
        foreach (var div in response.Css("#movie-featured > div"))
        {
            if (div.GetAttribute("class") != "clearfix")
            {
                var movie = new Movie
                {
                    Id = Convert.ToInt32(div.GetAttribute("data-movie-id")),
                    Title = div.Css("a")[0].TextContentClean,
                    URL = div.Css("a")[0].Attributes["href"]
                };
                Scrape(movie, "Movie.Jsonl");
            }
        }
    }
}
public class MovieScraper : WebScraper
{
    public override void Init()
    {
        License.LicenseKey = "LicenseKey";
        this.LoggingLevel = WebScraper.LogLevel.All;
        this.WorkingDirectory = AppSetting.GetAppRoot() + @"\MovieSample\Output\";
        this.Request("https://website.com/", Parse);
    }

    public override void Parse(Response response)
    {
        foreach (var div in response.Css("#movie-featured > div"))
        {
            if (div.GetAttribute("class") != "clearfix")
            {
                var movie = new Movie
                {
                    Id = Convert.ToInt32(div.GetAttribute("data-movie-id")),
                    Title = div.Css("a")[0].TextContentClean,
                    URL = div.Css("a")[0].Attributes["href"]
                };
                Scrape(movie, "Movie.Jsonl");
            }
        }
    }
}
Public Class MovieScraper
	Inherits WebScraper

	Public Overrides Sub Init()
		License.LicenseKey = "LicenseKey"
		Me.LoggingLevel = WebScraper.LogLevel.All
		Me.WorkingDirectory = AppSetting.GetAppRoot() & "\MovieSample\Output\"
		Me.Request("https://website.com/", AddressOf Parse)
	End Sub

	Public Overrides Sub Parse(ByVal response As Response)
		For Each div In response.Css("#movie-featured > div")
			If div.GetAttribute("class") <> "clearfix" Then
				Dim movie As New Movie With {
					.Id = Convert.ToInt32(div.GetAttribute("data-movie-id")),
					.Title = div.Css("a")(0).TextContentClean,
					.URL = div.Css("a")(0).Attributes("href")
				}
				Scrape(movie, "Movie.Jsonl")
			End If
		Next div
	End Sub
End Class
$vbLabelText   $csharpLabel

詳細頁面抓取

讓我們擴充我們的 Movie 類別,新增用於詳細資訊的屬性:

public class Movie
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string URL { get; set; }
    public string Description { get; set; }
    public List<string> Genre { get; set; }
    public List<string> Actor { get; set; }
}
public class Movie
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string URL { get; set; }
    public string Description { get; set; }
    public List<string> Genre { get; set; }
    public List<string> Actor { get; set; }
}
Public Class Movie
    Public Property Id As Integer
    Public Property Title As String
    Public Property URL As String
    Public Property Description As String
    Public Property Genre As List(Of String)
    Public Property Actor As List(Of String)
End Class
$vbLabelText   $csharpLabel

接著導航至"詳細資訊"頁面進行擷取,並運用 IronWebscraper 的進階功能:

public class MovieScraper : WebScraper
{
    public override void Init()
    {
        License.LicenseKey = "LicenseKey";
        this.LoggingLevel = WebScraper.LogLevel.All;
        this.WorkingDirectory = AppSetting.GetAppRoot() + @"\MovieSample\Output\";
        this.Request("https://domain/", Parse);
    }

    public override void Parse(Response response)
    {
        foreach (var div in response.Css("#movie-featured > div"))
        {
            if (div.GetAttribute("class") != "clearfix")
            {
                var movie = new Movie
                {
                    Id = Convert.ToInt32(div.GetAttribute("data-movie-id")),
                    Title = div.Css("a")[0].TextContentClean,
                    URL = div.Css("a")[0].Attributes["href"]
                };
                this.Request(movie.URL, ParseDetails, new MetaData() { { "movie", movie } });
            }
        }           
    }

    public void ParseDetails(Response response)
    {
        var movie = response.MetaData.Get<Movie>("movie");
        var div = response.Css("div.mvic-desc")[0];
        movie.Description = div.Css("div.desc")[0].TextContentClean;
        movie.Genre = div.Css("div > p > a").Select(element => element.TextContentClean).ToList();
        movie.Actor = div.Css("div > p:nth-child(2) > a").Select(element => element.TextContentClean).ToList();

        Scrape(movie, "Movie.Jsonl");
    }
}
public class MovieScraper : WebScraper
{
    public override void Init()
    {
        License.LicenseKey = "LicenseKey";
        this.LoggingLevel = WebScraper.LogLevel.All;
        this.WorkingDirectory = AppSetting.GetAppRoot() + @"\MovieSample\Output\";
        this.Request("https://domain/", Parse);
    }

    public override void Parse(Response response)
    {
        foreach (var div in response.Css("#movie-featured > div"))
        {
            if (div.GetAttribute("class") != "clearfix")
            {
                var movie = new Movie
                {
                    Id = Convert.ToInt32(div.GetAttribute("data-movie-id")),
                    Title = div.Css("a")[0].TextContentClean,
                    URL = div.Css("a")[0].Attributes["href"]
                };
                this.Request(movie.URL, ParseDetails, new MetaData() { { "movie", movie } });
            }
        }           
    }

    public void ParseDetails(Response response)
    {
        var movie = response.MetaData.Get<Movie>("movie");
        var div = response.Css("div.mvic-desc")[0];
        movie.Description = div.Css("div.desc")[0].TextContentClean;
        movie.Genre = div.Css("div > p > a").Select(element => element.TextContentClean).ToList();
        movie.Actor = div.Css("div > p:nth-child(2) > a").Select(element => element.TextContentClean).ToList();

        Scrape(movie, "Movie.Jsonl");
    }
}
Public Class MovieScraper
	Inherits WebScraper

	Public Overrides Sub Init()
		License.LicenseKey = "LicenseKey"
		Me.LoggingLevel = WebScraper.LogLevel.All
		Me.WorkingDirectory = AppSetting.GetAppRoot() & "\MovieSample\Output\"
		Me.Request("https://domain/", AddressOf Parse)
	End Sub

	Public Overrides Sub Parse(ByVal response As Response)
		For Each div In response.Css("#movie-featured > div")
			If div.GetAttribute("class") <> "clearfix" Then
				Dim movie As New Movie With {
					.Id = Convert.ToInt32(div.GetAttribute("data-movie-id")),
					.Title = div.Css("a")(0).TextContentClean,
					.URL = div.Css("a")(0).Attributes("href")
				}
				Me.Request(movie.URL, AddressOf ParseDetails, New MetaData() From {
					{ "movie", movie }
				})
			End If
		Next div
	End Sub

	Public Sub ParseDetails(ByVal response As Response)
		Dim movie = response.MetaData.Get(Of Movie)("movie")
		Dim div = response.Css("div.mvic-desc")(0)
		movie.Description = div.Css("div.desc")(0).TextContentClean
		movie.Genre = div.Css("div > p > a").Select(Function(element) element.TextContentClean).ToList()
		movie.Actor = div.Css("div > p:nth-child(2) > a").Select(Function(element) element.TextContentClean).ToList()

		Scrape(movie, "Movie.Jsonl")
	End Sub
End Class
$vbLabelText   $csharpLabel

IronWebscraper程式庫功能

HttpIdentity 功能

某些系統要求使用者必須登入才能瀏覽內容; 請使用 HttpIdentity 作為憑證:

HttpIdentity id = new HttpIdentity
{
    NetworkUsername = "username",
    NetworkPassword = "pwd"
};
Identities.Add(id);
HttpIdentity id = new HttpIdentity
{
    NetworkUsername = "username",
    NetworkPassword = "pwd"
};
Identities.Add(id);
Dim id As New HttpIdentity With {
	.NetworkUsername = "username",
	.NetworkPassword = "pwd"
}
Identities.Add(id)
$vbLabelText   $csharpLabel

啟用網頁快取

在開發過程中將請求的頁面快取以供重複使用:

public override void Init()
{
    License.LicenseKey = "LicenseKey";
    this.LoggingLevel = WebScraper.LogLevel.All;
    this.WorkingDirectory = AppSetting.GetAppRoot() + @"\ShoppingSiteSample\Output\";
    EnableWebCache();
    this.Request("http://www.WebSite.com", Parse);
}
public override void Init()
{
    License.LicenseKey = "LicenseKey";
    this.LoggingLevel = WebScraper.LogLevel.All;
    this.WorkingDirectory = AppSetting.GetAppRoot() + @"\ShoppingSiteSample\Output\";
    EnableWebCache();
    this.Request("http://www.WebSite.com", Parse);
}
Public Overrides Sub Init()
	License.LicenseKey = "LicenseKey"
	Me.LoggingLevel = WebScraper.LogLevel.All
	Me.WorkingDirectory = AppSetting.GetAppRoot() & "\ShoppingSiteSample\Output\"
	EnableWebCache()
	Me.Request("http://www.WebSite.com", Parse)
End Sub
$vbLabelText   $csharpLabel

流量限制

控制連線數量與速度:

public override void Init()
{
    License.LicenseKey = "LicenseKey";
    this.LoggingLevel = WebScraper.LogLevel.All;
    this.WorkingDirectory = AppSetting.GetAppRoot() + @"\ShoppingSiteSample\Output\";
    this.MaxHttpConnectionLimit = 80;
    this.RateLimitPerHost = TimeSpan.FromMilliseconds(50);
    this.OpenConnectionLimitPerHost = 25;
    this.ObeyRobotsDotTxt = false;
    this.ThrottleMode = Throttle.ByDomainHostName;
    this.Request("https://www.Website.com", Parse);
}
public override void Init()
{
    License.LicenseKey = "LicenseKey";
    this.LoggingLevel = WebScraper.LogLevel.All;
    this.WorkingDirectory = AppSetting.GetAppRoot() + @"\ShoppingSiteSample\Output\";
    this.MaxHttpConnectionLimit = 80;
    this.RateLimitPerHost = TimeSpan.FromMilliseconds(50);
    this.OpenConnectionLimitPerHost = 25;
    this.ObeyRobotsDotTxt = false;
    this.ThrottleMode = Throttle.ByDomainHostName;
    this.Request("https://www.Website.com", Parse);
}
Public Overrides Sub Init()
	License.LicenseKey = "LicenseKey"
	Me.LoggingLevel = WebScraper.LogLevel.All
	Me.WorkingDirectory = AppSetting.GetAppRoot() & "\ShoppingSiteSample\Output\"
	Me.MaxHttpConnectionLimit = 80
	Me.RateLimitPerHost = TimeSpan.FromMilliseconds(50)
	Me.OpenConnectionLimitPerHost = 25
	Me.ObeyRobotsDotTxt = False
	Me.ThrottleMode = Throttle.ByDomainHostName
	Me.Request("https://www.Website.com", Parse)
End Sub
$vbLabelText   $csharpLabel

限流屬性

  • MaxHttpConnectionLimit
    允許的 HTTP 請求(執行緒)總數
  • RateLimitPerHost
    向特定網域或 IP 位址發送請求之間的最小禮貌延遲(暫停時間)
  • OpenConnectionLimitPerHost
    每個主機名稱或 IP 位址允許的同時 HTTP 請求(執行緒)數量
  • ThrottleMode
    使 WEBSCRAPER 能智慧地限制請求頻率,不僅依據主機名稱,亦依據主機伺服器的 IP 位址進行限制。 此表述旨在禮貌地處理可能發生於同一台伺服器上託管多個被抓取網域的情況。

附錄

如何建立 Windows 表單應用程式?

請使用 Visual Studio 2013 或更高版本。

  1. 開啟 Visual Studio。
  2. 檔案 -> 新增 -> 專案 Enterprise 2015

  3. 選擇 Visual C# 或 VB -> Windows -> Windows Forms 應用程式。 建立 Windows 應用程式

專案名稱IronScraperSample
位置:請在您的磁碟上選擇一個位置。

如何建立 ASP.NET Web Form 應用程式?

  1. 開啟 Visual Studio。 Enterprise 2015

  2. 檔案 -> 新增 -> 專案 檔案 > 新增專案

  3. 選擇 Visual C# 或 VB -> Web -> ASP.NET Web Application (.NET Framework)。 ASP .NET 網頁應用程式

專案名稱IronScraperSample
位置:請在您的磁碟上選擇一個位置。

  1. 在您的 ASP.NET 範本中,選取一個空白範本並勾選"Web Forms"。 ASP .NET 範本

  2. 您的基本 ASP.NET Web Form 專案已建立。 ASP .NET Web Form 專案

請在此處下載完整的教學範例專案程式碼

常見問題

如何使用 C# 從網站抓取資料?

您可以使用 IronWebScraper 在 C# 中從網站抓取資料。首先透過 NuGet 安裝此程式庫,並建立一個基本的控制台應用程式,即可開始高效地擷取網頁資料。

在 C# 中進行網頁擷取有哪些先決條件?

若要在 C# 中進行網頁擷取,您應具備 C# 或 VB.NET 的基礎程式設計能力,並理解 HTML、JavaScript 和 CSS 等網頁技術,同時熟悉 DOM、XPath 及 CSS 選擇器。

如何在 .NET 專案中安裝網頁抓取函式庫?

要在 .NET 專案中安裝 IronWebScraper,請使用 NuGet 套件管理員控制台並執行命令 Install-Package IronWebScraper,或透過 Visual Studio 中的 NuGet 套件管理員介面進行操作。

我該如何在網頁爬蟲中實作請求限流?

IronWebscraper 允許您實作請求限流機制,以管理發送至伺服器的請求頻率。此功能可透過 MaxHttpConnectionLimitRateLimitPerHostOpenConnectionLimitPerHost 等設定進行配置。

在網頁抓取中啟用網頁快取的目的是什麼?

在網頁抓取中啟用網頁快取,可透過儲存並重複使用先前回應,從而減少傳送至伺服器的請求數量。此功能可在 IronWebscraper 中透過 EnableWebCache 方法進行設定。

在網頁爬取中應如何處理驗證機制?

透過 IronWebscraper,您可以使用 HttpIdentity 來管理驗證機制,從而存取登入表單後方或受限區域的內容,進而實現受保護資源的擷取。

C# 語言中,網頁擷取工具的簡單範例是什麼?

「HelloScraper」是教學中提供的簡單範例。它示範了如何使用 IronWebscraper 建立基本的網頁擷取程式,包括如何發起請求及解析回應。

如何擴展我的網頁抓取工具以處理複雜的頁面結構?

Using IronWebScraper,您可以自訂 Parse 方法來處理不同類型的網頁,藉此擴展您的爬蟲程式以應對複雜的頁面結構,從而實現靈活的資料擷取策略。

使用網頁抓取函式庫有哪些好處?

使用 IronWebscraper 這樣的網頁抓取程式庫,能帶來諸如簡化資料擷取、網域管理、請求限流、快取以及支援驗證等優勢,從而有效率地處理網頁抓取任務。

Curtis Chau
技術撰稿人

Curtis Chau 擁有卡爾頓大學(Carleton University)的電腦科學學士學位,專精於前端開發,並精通 Node.js、TypeScript、JavaScript 及 React。他熱衷於打造直觀且美觀的用戶介面,喜歡運用現代框架,並創建結構完善、視覺上吸引人的手冊。

除了開發工作之外,Curtis 對物聯網(IoT)抱有濃厚興趣,致力於探索整合硬體與軟體的創新方法。閒暇時,他喜歡玩遊戲和開發 Discord 機器人,將對科技的熱愛與創意相結合。

準備開始了嗎?
Nuget 下載 137,906 | 版本: 2026.6 just released
Still Scrolling Icon

還在捲動嗎?

想要快速證明? PM > Install-Package IronWebScraper
執行範例 觀看您的目標網站成為結構化資料。