如何使用 C# 進行網站資料擷取

.NET軟體工程師 對很多人來說,這是從 .NET 生成 PDF 文件的最有效方法,因為不需要學習額外的 API 或導航複雜的設計系統
艾哈邁德·阿布爾馬格德
2018年10月28日
已更新 2024年12月22日
分享:
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


目標受眾

本教程面向具備基本或高級編程技能的軟體開發人員,他們希望構建和實現用於高級抓取功能(網站抓取、網站數據收集和提取、網站內容解析、網頁收集)的解決方案。

網路資料擷取從來不是一項簡單的任務,C# 或 .NET 編程環境中並無主導框架可用。Iron Web Scraper 的創建改變了這一點

所需技能

  1. 使用 Microsoft 程式設計語言(如 C# 或 VB.NET)的基本編程技巧基礎。

  2. 基本瞭解網路技術(HTML、JavaScript、JQuery、CSS 等)及其運作方式

  3. 基本的 DOM、XPath、HTML 和 CSS 選擇器知識

工具

  1. Microsoft Visual Studio 2010 或更高版本

  2. 瀏覽器(如 Chrome 的網頁檢查器或 Firefox 的 Firebug)的網頁開發者擴充功能

為什麼要進行網頁抓取?

(原因和概念)

如果您想要建立一個具有以下能力的產品或解決方案:

  1. 提取網站數據

  2. 從多個網站比較內容、價格、功能等。

  3. 掃描和快取網站內容

    如果您基於上述一個或多個原因,那麼IronWebscraper是一個非常適合您需求的函式庫。

如何安裝IronWebScraper?

在您建立新專案後(見附錄A),您可以通過使用NuGet自動插入或手動安裝DLL的方式將IronWebScraper庫添加到您的專案中。

使用 NuGet 安裝

要使用 NuGet 將 IronWebScraper 庫添加到我們的專案中,我們可以使用視覺介面(NuGet 套件管理器)或通過使用套件管理器控制台的命令來完成。

使用 NuGet 套件管理器

  1. 使用滑鼠 -> 右鍵點擊項目名稱 -> 選擇管理 NuGet 套件

    AddIronWebscraperUsingGUI related to 使用 NuGet 套件管理器

  2. 從瀏覽標籤 -> 搜尋 IronWebScraper -> 安裝

    AddIronWebscraperUsingGUI2 related to 使用 NuGet 套件管理器

  3. 点选确定

    AddIronWebscraperUsingGUI3 related to 使用 NuGet 套件管理器

  4. 完成了。

    AddIronWebscraperUsingGUI4 related to 使用 NuGet 套件管理器

使用 NuGet 套件控制台

  1. 從工具 -> NuGet 套件管理器 -> 套件管理器控制台

    AddIronWebscraperUsingConsole related to 使用 NuGet 套件控制台

  2. 選擇類別庫專案作為預設專案

  3. 執行命令 -> Install-Package IronWebScraper

    AddIronWebscraperUsingConsole1 related to 使用 NuGet 套件控制台

手動安裝

  1. 前往 ironsoftware.com

  2. 點擊IronWebScraper或直接使用網址https://ironsoftware.com/csharp/webscraper/訪問其頁面

  3. 點擊下載DLL。

  4. 解壓縮已下載的壓縮檔案

  5. 在 Visual Studio 中右鍵點擊專案 -> 加入 -> 參考 -> 瀏覽

    AddIronWebscraperUsingDll related to 手動安裝

  6. 前往提取的資料夾 -> netstandard2.0 -> 然後選擇所有.dll檔案

    AddIronWebscraperUsingDll2 related to 手動安裝

  7. 完成了!

HelloScraper - 我們的第一個 IronWebScraper 範例

像往常一樣,我們將開始實現 Hello Scraper 應用程式,以使用 IronWebScraper 進行我們的第一步。

  • 我們已創建一個名為“IronWebScraperSample”的新控制台應用程式。

    創建IronWebscraper範例的步驟###

  1. 創建一個資料夾,並將其命名為“HelloScraperSample”。

  2. 然後新建一個類並命名為“HelloScraper”

    HelloScraperAddClass related to HelloScraper - 我們的第一個 IronWebScraper 範例

  3. 將此程式碼片段新增到HelloScraper
public class HelloScraper : WebScraper
{
        /// <summary>
        /// Override this method 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; // All Events Are Logged
            this.Request("https://blog.scrapinghub.com", Parse);
        }

        /// <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 title_link in response.Css("h2.entry-title a"))
            {
                // Read Link Text
                string strTitle = title_link.TextContentClean;
                // Save Result to File
                Scrape(new ScrapedData() { { "Title", strTitle } }, "HelloScraper.json");
            }
            // Loop On All Links
            if (response.CssExists("div.prev-post > a [href]"))
            {
                // Get Link URL
                var next_page = response.Css("div.prev-post > a [href]")[0].Attributes ["href"];
                // Scrape Next URL
                this.Request(next_page, Parse);
            }
        }
}
public class HelloScraper : WebScraper
{
        /// <summary>
        /// Override this method 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; // All Events Are Logged
            this.Request("https://blog.scrapinghub.com", Parse);
        }

        /// <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 title_link in response.Css("h2.entry-title a"))
            {
                // Read Link Text
                string strTitle = title_link.TextContentClean;
                // Save Result to File
                Scrape(new ScrapedData() { { "Title", strTitle } }, "HelloScraper.json");
            }
            // Loop On All Links
            if (response.CssExists("div.prev-post > a [href]"))
            {
                // Get Link URL
                var next_page = response.Css("div.prev-post > a [href]")[0].Attributes ["href"];
                // Scrape Next URL
                this.Request(next_page, Parse);
            }
        }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel
  1. 現在開始抓取,將此代碼片段添加到主要部分
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();
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel
  1. 結果將會被儲存為 WebSraper.WorkingDirecty/classname.Json 格式的文件。

    HelloScraperFrmFileResult related to HelloScraper - 我們的第一個 IronWebScraper 範例

代碼概述

Scrape.Start() => 啟動後會執行以下的網頁抓取邏輯:

  1. 首先調用 Init() 方法來初始化變數、抓取屬性和行為屬性。

  2. 正如我們所見,它將起始頁面設置為 Request("https://blog.scrapinghub.com", Parse),並將 Parse (Response response) 定義為用於解析響應的過程。

  3. Webscraper 同時管理:http 和執行緒... 保持您的所有代碼易於調試和同步。

  4. 在 Init() 之後啟動 Parse 方法來解析頁面。
    1. 您可以使用(CSS選擇器、JavaScript DOM、XPath)來尋找元素。

    2. 選定的元素被轉換為 ScrapedData 類型,你可以將它們轉換為任何自定義類型,如 (Product, Employee, News 等)。

    3. 使用 Json 格式保存在 ("bin/Scrape/") 目錄中的文件中的對象。或者,您可以將文件的路徑設置為參數,稍後在其他示例中我們將看到。

IronWebScraper 程式庫功能與選項

您可以在使用手動安裝方法下載的壓縮檔中找到更新的文檔(IronWebScraper Documentation.chm 文件)。

或者您可以查看圖書館的線上文件,最後更新於https://ironsoftware.com/csharp/webscraper/object-reference/

要在您的專案中開始使用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
Properties \ functionsTypeDescription
Init ()Methodused to setup the scraper
Parse (Response response)MethodUsed to implement the logic that the scraper will use and how it will process it.
Coming table contain list of methods and properties that IronWebScraper Library are providing
NOTE : Can implement multiple method for different pages behaviors or structures
  • BannedUrls
  • AllowedUrls
  • BannedDomains
CollectionsUsed to ban/Allow/ URLs And/Or Domains
Ex: BannedUrls.Add ("*.zip", "*.exe", "*.gz", "*.pdf");
Note:
  • You can use ( * and/or ? ) wildcards
  • You can use strings and regular expressions
  • BannedUrls, AllowedUrls, BannedDomains, AllowedDomains
  • BannedUrls.Add ("*.zip", "*.exe", "*.gz", "*.pdf");
  • *? glob sale wildcards
  • strings and regular expressions
  • you can override this behavior by overriding the method: public virtual bool AcceptUrl (string url)
ObeyRobotsDotTxtBooleanUsed to enable or disable read and follow robots.txt its directive or not
public override bool ObeyRobotsDotTxtForHost (string Host)MethodUsed to enable or disable read and follow robots.txt its directive or not for certain domain
ScrapeMethod
ScrapeUniqueMethod
ThrottleModeEnumeration
EnableWebCache ()Method
EnableWebCache (TimeSpan cacheDuration)Method
MaxHttpConnectionLimitInt
RateLimitPerHostTimeSpan
OpenConnectionLimitPerHostInt
ObeyRobotsDotTxtBoolean
ThrottleModeEnumEnum Options:
  • ByIpAddress
  • ByDomainHostName
SetSiteSpecificCrawlRateLimit (string hostName, TimeSpan crawlRate)Method
IdentitiesCollectionsA list of HttpIdentity () to be used to fetch web resources.

Each Identity may have a different proxy IP addresses, user Agent, http headers, Persistent cookies, username and password.
Best practice is to create Identities in your WebScraper.Init Method and Add Them to this WebScraper.Identities List.
WorkingDirectorystringSetting working directory that will be used for all scrape related data will be stored to disk.


## 實際範例和練習

抓取線上電影網站

讓我們從一個真實世界的網站開始另一個例子。我們將選擇抓取一個電影網站。

讓我們新增一個類別並命名為「MovieScraper」:

MovieScrapaerAddClass related to 抓取線上電影網站

現在讓我們來看看我們將要抓取的網站:

123movies related to 抓取線上電影網站

這是我們在網站上看到的首頁 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 Divs in response.Css("#movie-featured > div"))
        {
            if (Divs.Attributes ["class"] != "clearfix")
            {
                var MovieId = Divs.GetAttribute("data-movie-id");
                var link = Divs.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 Divs in response.Css("#movie-featured > div"))
        {
            if (Divs.Attributes ["class"] != "clearfix")
            {
                var MovieId = Divs.GetAttribute("data-movie-id");
                var link = Divs.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 Divs In response.Css("#movie-featured > div")
			If Divs.Attributes ("class") <> "clearfix" Then
				Dim MovieId = Divs.GetAttribute("data-movie-id")
				Dim link = Divs.Css("a")(0)
				Dim MovieTitle = link.TextContentClean
				Scrape(New ScrapedData() From {
					{ "MovieId", MovieId },
					{ "MovieTitle", MovieTitle }
				},
				"Movie.Jsonl")
			End If
		Next Divs
	End Sub
End Class
$vbLabelText   $csharpLabel

這段程式碼有什麼新功能?

工作目錄屬性用於設置所有抓取數據及其相關文件的主要工作目錄。

讓我們做得更多。

如果我們需要構建類型化對象以保存格式化對象中的抓取數據,該怎麼辦?

讓我們實現一個電影類,用來存放我們格式化的數據:

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

現在我們將更新我們的代碼:

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 Divs in response.Css("#movie-featured > div"))
        {
            if (Divs.Attributes ["class"] != "clearfix")
            {
                var movie = new Movie();
                movie.Id = Convert.ToInt32( Divs.GetAttribute("data-movie-id"));
                var link = Divs.Css("a")[0];
                movie.Title = link.TextContentClean;
                movie.URL = link.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 Divs in response.Css("#movie-featured > div"))
        {
            if (Divs.Attributes ["class"] != "clearfix")
            {
                var movie = new Movie();
                movie.Id = Convert.ToInt32( Divs.GetAttribute("data-movie-id"));
                var link = Divs.Css("a")[0];
                movie.Title = link.TextContentClean;
                movie.URL = link.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 Divs In response.Css("#movie-featured > div")
			If Divs.Attributes ("class") <> "clearfix" Then
				Dim movie As New Movie()
				movie.Id = Convert.ToInt32(Divs.GetAttribute("data-movie-id"))
				Dim link = Divs.Css("a")(0)
				movie.Title = link.TextContentClean
				movie.URL = link.Attributes ("href")
				Scrape(movie, "Movie.Jsonl")
			End If
		Next Divs
	End Sub
End Class
$vbLabelText   $csharpLabel

有什麼新功能?

  1. 我們實現Movie Class來保存我們抓取的數據

  2. 我們將電影對象傳遞給 Scrape 方法,它了解我們的格式並以我們在此處看到的已定義格式保存:

    MovieResultMovieClass related to 抓取線上電影網站

    讓我們開始抓取更詳細的頁面。

電影頁面看起來像這樣:

MovieDetailsSample related to 抓取線上電影網站

```html

Guardians of the Galaxy Vol. 2

Set to the backdrop of Awesome Mixtape #2, Marvel's Guardians of the Galaxy Vol. 2 continues the team's adventures as they travel throughout the cosmos to help Peter Quill learn more about his true parentage.

Duration: 136 min

Quality: CAM

Release: 2017

IMDb: 8.3

``` 我們可以用新的屬性(描述、類型、演員、導演、國家、時長、IMDB 評分)來擴展我們的電影類別,但我們將只使用(描述、類型、演員)作為樣本。 ```cs public class Movie { public int Id { get; set; } public string Title { get; set; } public string URL { get; set; } public string Description { get; set; } public ListGenre { get; set; } public ListActor { get; set; } } ``` 現在我們將導航到詳細頁面進行抓取。 IronWebScraper 讓您可以增加更多抓取功能,以抓取不同類型的頁面格式。 如我們在此所見: ```cs 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 Divs in response.Css("#movie-featured > div")) { if (Divs.Attributes ["class"] != "clearfix") { var movie = new Movie(); movie.Id = Convert.ToInt32( Divs.GetAttribute("data-movie-id")); var link = Divs.Css("a")[0]; movie.Title = link.TextContentClean; movie.URL = link.Attributes ["href"]; this.Request(movie.URL, ParseDetails, new MetaData() { { "movie", movie } });// to scrap Detailed Page } } } public void ParseDetails(Response response) { var movie = response.MetaData.Get("movie"); var Div = response.Css("div.mvic-desc")[0]; movie.Description = Div.Css("div.desc")[0].TextContentClean; foreach(var Genre in Div.Css("div > p > a")) { movie.Genre.Add(Genre.TextContentClean); } foreach (var Actor in Div.Css("div > p:nth-child(2) > a")) { movie.Actor.Add(Actor.TextContentClean); } Scrape(movie, "Movie.Jsonl"); } } ``` *有什麼新功能?* 1. 我們可以添加抓取功能(ParseDetails)來抓取詳細頁面 2. 我們將生成檔案的 Scrape 功能移至新功能。 3. 我們使用了 IronWebscraper 功能(MetaData)將我們的電影物件傳遞給新的擷取功能 4. 我們抓取了網頁並將我們的電影對象數據保存到一個文件中。

MovieResultMovieClass1 related to 抓取線上電影網站

### 從購物網站抓取內容 我们选择一个购物网站来抓取其内容。

ShoppingSite related to 抓取線上電影網站

從圖片中可以看到,我們有一個左側欄,其中包含了網站產品類別的鏈接。 因此,我們的第一步是調查網站的HTML,並計劃我們希望如何抓取它。

ShoppingSiteLeftBar related to 抓取線上電影網站

時尚網站的類別有子類別(男性、女性、兒童) ```html``` 讓我們設立一個項目 1. 創建一個新的控制台應用程序或為我們的新範例添加一個名為“ShoppingSiteSample”的新文件夾。 2. 新增名為“ShoppingScraper”的類別 3. 首先將對網站的主類別及其子類別進行抓取 讓我們建立一個類別模型: ```cs public class Category { ////// Gets or sets the name. ///////// The name. ///public string Name { get; set; } ////// Gets or sets the URL. ///////// The URL. ///public string URL { get; set; } ////// Gets or sets the sub categories. ///////// The sub categories. ///public ListSubCategories { get; set; } } ``` 4. 現在讓我們構建我們的抓取邏輯 ```cs public class ShoppingScraper : WebScraper { ////// Override this method initialize your web-scraper. /// Important tasks will be to Request at least one start url... and set allowed/banned domain or url patterns. ///public override void Init() { License.LicenseKey = "LicenseKey"; this.LoggingLevel = WebScraper.LogLevel.All; this.WorkingDirectory = AppSetting.GetAppRoot() + @"\ShoppingSiteSample\Output\"; this.Request("www.webSite.com", Parse); } ////// 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. //////The http Response object to parsepublic override void Parse(Response response) { var categoryList = new List(); foreach (var Links in response.Css("#menuFixed > ul > li > a ")) { var cat = new Category(); cat.URL = Links.Attributes ["href"]; cat.Name = Links.InnerText; categoryList.Add(cat); } Scrape(categoryList, "Shopping.Jsonl"); } } ``` 從菜單刮取鏈接

ShoppingSiteScrapeMenu related to 抓取線上電影網站

讓我們更新代碼來抓取主要類別及其所有子鏈接 ```cs public override void Parse(Response response) { // List of Categories Links (Root) var categoryList = new List(); foreach (var li in response.Css("#menuFixed > ul > li")) { // List Of Main Links foreach (var Links in li.Css("a")) { var cat = new Category(); cat.URL = Links.Attributes ["href"]; cat.Name = Links.InnerText; cat.SubCategories = new List(); // List of Sub Catgories Links foreach (var subCategory in li.Css("a [class=subcategory]")) { var subcat = new Category(); subcat.URL = Links.Attributes ["href"]; subcat.Name = Links.InnerText; // Check If Link Exist Before if (cat.SubCategories.Find(c=>c.Name== subcat.Name && c.URL == subcat.URL) == null) { // Add Sublinks cat.SubCategories.Add(subcat); } } // Add Categories categoryList.Add(cat); } } Scrape(categoryList, "Shopping.Jsonl"); } ``` 現在我們有了所有網站分類的連結,讓我們開始抓取每個分類中的產品。 讓我們導航到任何類別並檢查內容。

ProductSubCategoryList related to 抓取線上電影網站

讓我們看看它的代碼 ```html
``` 讓我們為這個內容建立我們的產品模型。 ```cs public class Product { ////// Gets or sets the name. ///////// The name. ///public string Name { get; set; } ////// Gets or sets the price. ///////// The price. ///public string Price { get; set; } ////// Gets or sets the image. ///////// The image. ///public string Image { get; set; } } ``` 若要抓取分類頁面,我們新增一個抓取方法: ```cs public void ParseCatgory(Response response) { // List of Products Links (Root) var productList = new List(); foreach (var Links in response.Css("body > main > section.osh-content > section.products > div > a")) { var product = new Product(); product.Name = Links.InnerText; product.Image = Links.Css("div.image-wrapper.default-state > img")[0].Attributes ["src"]; productList.Add(product); } Scrape(productList, "Products.Jsonl"); } ``` ### 高級網頁抓取功能 #### HttpIdentity 功能: 一些網站系統要求使用者登入後才能查看內容; 在這種情況下,我們可以使用 HttpIdentity: - ```cs HttpIdentity id = new HttpIdentity(); id.NetworkUsername = "username"; id.NetworkPassword = "pwd"; Identities.Add(id); ``` IronWebScraper最令人印象深刻且強大的功能之一是能夠使用成千上萬的唯一(用戶憑據和/或瀏覽器引擎)來偽裝或抓取網站,使用多重登入會話。 ```cs public override void Init() { License.LicenseKey = " LicenseKey "; this.LoggingLevel = WebScraper.LogLevel.All; this.WorkingDirectory = AppSetting.GetAppRoot() + @"\ShoppingSiteSample\Output\"; var proxies = "IP-Proxy1: 8080,IP-Proxy2: 8081".Split(','); foreach (var UA in IronWebScraper.CommonUserAgents.ChromeDesktopUserAgents) { foreach (var proxy in proxies) { Identities.Add(new HttpIdentity() { UserAgent = UA, UseCookies = true, Proxy = proxy }); } } this.Request("http://www.Website.com", Parse); } ``` 您有多個屬性可以提供不同的行為,因此可以防止網站封鎖您。 以下是其中一些屬性: - * **NetworkDomain** : 用於使用者驗證的網域。 支持Windows、NTLM、Kerberos、Linux、BSD和Mac OS X網絡。 必須與 (NetworkUsername 和 NetworkPassword) 一起使用 * **NetworkUsername**:用於用戶驗證的網絡/HTTP 用戶名。 支持 Http、Windows 網路、NTLM、Kerberos、Linux 網路、BSD 網路和 Mac OS。 * **NetworkPassword**:用於用戶身份驗證的網路/HTTP 密碼。 支持Http、Windows網絡、NTLM、Keroberos、Linux網絡、BSD網絡和Mac OS。 * **代理**:設定代理設定 * **UserAgent**:設定瀏覽器引擎(Chrome 桌面版、Chrome 手機版、Chrome 平板版、IE 和 Firefox 等)。 * **HttpRequestHeaders**:適用於自定義標頭值,將與此身份一起使用,並接受字典對象(Dictionary) * **UseCookies**:啟用/禁用使用 cookies IronWebScraper 使用隨機身份運行抓取器。 如果我們需要指定使用特定的身份來解析頁面,我們可以這樣做。 ```cs public override void Init() { License.LicenseKey = " LicenseKey "; this.LoggingLevel = WebScraper.LogLevel.All; this.WorkingDirectory = AppSetting.GetAppRoot() + @"\ShoppingSiteSample\Output\"; HttpIdentity identity = new HttpIdentity(); identity.NetworkUsername = "username"; identity.NetworkPassword = "pwd"; Identities.Add(id); this.Request("http://www.Website.com", Parse, identity); } ``` #### 啟用網頁快取功能: 此功能用於緩存請求的頁面。 它經常在開發和測試階段使用; 允許開發者在更新代碼後緩存所需的頁面以供重用。 這使您能夠在重新啟動您的網頁抓取工具後在緩存的頁面上執行您的代碼,而不需要每次都連接到實時網站(行動重播)。 *您可以在 Init() 方法中使用它* 啟用網頁緩存(); 或 啟用網路快取(時間跨度到期); 它將您的快取資料儲存到工作目錄資料夾下的WebCache資料夾中。 ```cs public override void Init() { License.LicenseKey = " LicenseKey "; this.LoggingLevel = WebScraper.LogLevel.All; this.WorkingDirectory = AppSetting.GetAppRoot() + @"\ShoppingSiteSample\Output\"; EnableWebCache(new TimeSpan(1,30,30)); this.Request("http://www.WebSite.com", Parse); } ``` IronWebScraper 也具備一些功能,能夠讓您的引擎在重啟代碼後繼續抓取,通過使用 Start(CrawlID) 設定引擎的啟動過程名稱來實現。 ```cs static void Main(string [] args) { // Create Object From Scraper class EngineScraper scrape = new EngineScraper(); // Start Scraping scrape.Start("enginestate"); } ``` 執行請求和回應將被保存到工作目錄內的 SavedState 資料夾中。 #### 限流 我們可以控制每個域的最小和最大連接數以及連接速度。 ```cs public override void Init() { License.LicenseKey = "LicenseKey"; this.LoggingLevel = WebScraper.LogLevel.All; this.WorkingDirectory = AppSetting.GetAppRoot() + @"\ShoppingSiteSample\Output\"; // Gets or sets the total number of allowed open HTTP requests (threads) this.MaxHttpConnectionLimit = 80; // Gets or sets minimum polite delay (pause)between request to a given domain or IP address. this.RateLimitPerHost = TimeSpan.FromMilliseconds(50); // Gets or sets the allowed number of concurrent HTTP requests (threads) per hostname // or IP address. This helps protect hosts against too many requests. this.OpenConnectionLimitPerHost = 25; this.ObeyRobotsDotTxt = false; // Makes the WebSraper intelligently throttle requests not only by hostname, but // also by host servers' IP addresses. This is polite in-case multiple scraped domains // are hosted on the same machine. this.ThrottleMode = Throttle.ByDomainHostName; this.Request("https://www.Website.com", Parse); } ``` **限制屬性** * **MaxHttpConnectionLimit**
允許開啟的 HTTP 請求(線程)的總數 * **RateLimitPerHost**
對給定的域或 IP 地址的請求之間的最小禮貌延遲或暫停(以毫秒為單位) * **OpenConnectionLimitPerHost**
允許的同時 HTTP 請求(線程)數量 * **ThrottleMode**
使 IronWebscraper 不僅按主機名,還按主機伺服器的 IP 地址智能地調節請求。 这是礼貌的做法,以防多个抓取的域名托管在同一台机器上。 ## 附錄 ### 如何創建Windows表單應用程序? 我們應該使用 Visual Studio 2013 或更高版本來進行這項工作。 按照以下步驟創建一個新的 Windows Forms 項目: 1. 打開 Visual Studio

Enterprise2015 related to 抓取線上電影網站

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

FileNewProject related to 抓取線上電影網站

3. 從範本中,選擇程式語言(Visual C# 或 VB)-> Windows -> Windows Forms 應用程式

CreateWindowsApp related to 抓取線上電影網站

**專案名稱**:IronScraperSample
**位置**: 選擇硬碟上的一個位置

WindowsAppMainScreen related to 抓取線上電影網站

### 如何創建網絡表單應用程序? 您應該使用 Visual Studio 2013 或更高版本來進行此操作。 按照以下步驟創建一個新的 Asp.NET 網頁表單專案 1. 打開 Visual Studio

Enterprise2015 related to 抓取線上電影網站

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

FileNewProject related to 抓取線上電影網站

3. 從範本中選擇程式語言(Visual C# 或 VB)-> 網頁 -> ASP.NET Web 應用程式(.NET Framework)。

ASPNETWebApplication related to 抓取線上電影網站

**專案名稱**:IronScraperSample
**位置**:從硬碟中選擇一個位置 4. 從您的 ASP.NET 模板
  1. 選擇空白模板
  2. 檢查網頁表單
  3. ASPNETTemplates related to 抓取線上電影網站

5. 現在您的基本 ASP.NET 網頁表單專案已建立

ASPNETWebFormProject related to 抓取線上電影網站

[點擊此處](/downloads/assets/tutorials/webscraping-in-c-sharp/IronWebScraperSample.zip)下載完整的教程示例項目代碼項目。
.NET軟體工程師 對很多人來說,這是從 .NET 生成 PDF 文件的最有效方法,因為不需要學習額外的 API 或導航複雜的設計系統
艾哈邁德·阿布爾馬格德
跨國IT公司 .NET 軟體解決方案架構師

艾哈邁德是一位經驗豐富且認證過的微軟技術專家,擁有超過10年的 IT 和軟體開發經驗。他曾在多家公司工作,現任一家跨國 IT 公司的國家經理。

艾哈邁德與 IronPDF 和 IronWebScraper 合作已有一年多,並在他的公司多個專案中運用這些技術。