如何使用 C# 進行網站資料擷取
IronWebscraper 是用於網絡抓取、網絡數據提取和網絡內容解析的 .NET 程式庫。 它是一個易於使用的庫,可以添加到 Microsoft Visual Studio 項目中,以用於開發和生產。
IronWebscraper 擁有許多獨特的功能和能力,例如控制允許和禁止的頁面、對象、媒體等。它還允許管理多個身份、網絡緩存以及許多其他功能,我們將在本教程中進行介紹。
開始使用IronWebscraper
立即在您的專案中使用IronWebScraper,並享受免費試用。
目標受眾
本教程面向具備基本或高級編程技能的軟體開發人員,他們希望構建和實現用於高級抓取功能(網站抓取、網站數據收集和提取、網站內容解析、網頁收集)的解決方案。

所需技能
使用 Microsoft 程式設計語言(如 C# 或 VB.NET)的基本編程技巧基礎。
基本瞭解網路技術(HTML、JavaScript、JQuery、CSS 等)及其運作方式
- 基本的 DOM、XPath、HTML 和 CSS 選擇器知識
工具
Microsoft Visual Studio 2010 或更高版本
- 瀏覽器(如 Chrome 的網頁檢查器或 Firefox 的 Firebug)的網頁開發者擴充功能
為什麼要進行網頁抓取?
(原因和概念)
如果您想要建立一個具有以下能力的產品或解決方案:
提取網站數據
從多個網站比較內容、價格、功能等。
掃描和快取網站內容
如果您基於上述一個或多個原因,那麼IronWebscraper是一個非常適合您需求的函式庫。
如何安裝IronWebScraper?
在您建立新專案後(見附錄A),您可以通過使用NuGet自動插入或手動安裝DLL的方式將IronWebScraper庫添加到您的專案中。
使用 NuGet 安裝
要使用 NuGet 將 IronWebScraper 庫添加到我們的專案中,我們可以使用視覺介面(NuGet 套件管理器)或通過使用套件管理器控制台的命令來完成。
使用 NuGet 套件管理器
使用 NuGet 套件控制台
手動安裝
點擊IronWebScraper或直接使用網址https://ironsoftware.com/csharp/webscraper/訪問其頁面
點擊下載DLL。
解壓縮已下載的壓縮檔案
在 Visual Studio 中右鍵點擊專案 -> 加入 -> 參考 -> 瀏覽
前往提取的資料夾 ->
netstandard2.0
-> 然後選擇所有.dll
檔案- 完成了!
HelloScraper - 我們的第一個 IronWebScraper 範例
像往常一樣,我們將開始實現 Hello Scraper 應用程式,以使用 IronWebScraper 進行我們的第一步。
我們已創建一個名為“IronWebScraperSample”的新控制台應用程式。
創建IronWebscraper範例的步驟###
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
- 現在開始抓取,將此代碼片段添加到主要部分
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
代碼概述
Scrape.Start() => 啟動後會執行以下的網頁抓取邏輯:
首先調用 Init() 方法來初始化變數、抓取屬性和行為屬性。
正如我們所見,它將起始頁面設置為 Request("https://blog.scrapinghub.com", Parse),並將 Parse (Response response) 定義為用於解析響應的過程。
Webscraper 同時管理:http 和執行緒... 保持您的所有代碼易於調試和同步。
- 在 Init() 之後啟動 Parse 方法來解析頁面。
您可以使用(CSS選擇器、JavaScript DOM、XPath)來尋找元素。
選定的元素被轉換為 ScrapedData 類型,你可以將它們轉換為任何自定義類型,如 (Product, Employee, News 等)。
使用 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
Properties \ functions | Type | Description |
---|---|---|
Init () | Method | used to setup the scraper |
Parse (Response response) | Method | Used 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 |
| Collections | Used to ban/Allow/ URLs And/Or Domains Ex: BannedUrls.Add ("*.zip", "*.exe", "*.gz", "*.pdf"); Note:
|
ObeyRobotsDotTxt | Boolean | Used to enable or disable read and follow robots.txt its directive or not |
public override bool ObeyRobotsDotTxtForHost (string Host) | Method | Used to enable or disable read and follow robots.txt its directive or not for certain domain |
Scrape | Method | |
ScrapeUnique | Method | |
ThrottleMode | Enumeration | |
EnableWebCache () | Method | |
EnableWebCache (TimeSpan cacheDuration) | Method | |
MaxHttpConnectionLimit | Int | |
RateLimitPerHost | TimeSpan | |
OpenConnectionLimitPerHost | Int | |
ObeyRobotsDotTxt | Boolean | |
ThrottleMode | Enum | Enum Options:
|
SetSiteSpecificCrawlRateLimit (string hostName, TimeSpan crawlRate) | Method | |
Identities | Collections | A 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. |
WorkingDirectory | string | Setting working directory that will be used for all scrape related data will be stored to disk. |
## 實際範例和練習
抓取線上電影網站
讓我們從一個真實世界的網站開始另一個例子。我們將選擇抓取一個電影網站。
讓我們新增一個類別並命名為「MovieScraper」:
現在讓我們來看看我們將要抓取的網站:
這是我們在網站上看到的首頁 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>
正如我們所見,我們有電影 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
這段程式碼有什麼新功能?
工作目錄屬性用於設置所有抓取數據及其相關文件的主要工作目錄。
讓我們做得更多。
如果我們需要構建類型化對象以保存格式化對象中的抓取數據,該怎麼辦?
讓我們實現一個電影類,用來存放我們格式化的數據:
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
現在我們將更新我們的代碼:
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
有什麼新功能?
電影頁面看起來像這樣:
```htmlGuardians of the Galaxy Vol. 2
Genre: Action, Adventure, Sci-Fi
Actor: Chris Pratt, Zoe Saldana, Dave Bautista
Director: James Gunn
Country: United States
Duration: 136 min
Quality: CAM
Release: 2017
IMDb: 8.3
允許開啟的 HTTP 請求(線程)的總數 * **RateLimitPerHost**
對給定的域或 IP 地址的請求之間的最小禮貌延遲或暫停(以毫秒為單位) * **OpenConnectionLimitPerHost**
允許的同時 HTTP 請求(線程)數量 * **ThrottleMode**
使 IronWebscraper 不僅按主機名,還按主機伺服器的 IP 地址智能地調節請求。 这是礼貌的做法,以防多个抓取的域名托管在同一台机器上。 ## 附錄 ### 如何創建Windows表單應用程序? 我們應該使用 Visual Studio 2013 或更高版本來進行這項工作。 按照以下步驟創建一個新的 Windows Forms 項目: 1. 打開 Visual Studio2. 檔案 -> 新增 -> 專案3. 從範本中,選擇程式語言(Visual C# 或 VB)-> Windows -> Windows Forms 應用程式**專案名稱**:IronScraperSample
**位置**: 選擇硬碟上的一個位置### 如何創建網絡表單應用程序? 您應該使用 Visual Studio 2013 或更高版本來進行此操作。 按照以下步驟創建一個新的 Asp.NET 網頁表單專案 1. 打開 Visual Studio2. 檔案 -> 新增 -> 專案3. 從範本中選擇程式語言(Visual C# 或 VB)-> 網頁 -> ASP.NET Web 應用程式(.NET Framework)。**專案名稱**:IronScraperSample
**位置**:從硬碟中選擇一個位置 4. 從您的 ASP.NET 模板5. 現在您的基本 ASP.NET 網頁表單專案已建立[點擊此處](/downloads/assets/tutorials/webscraping-in-c-sharp/IronWebScraperSample.zip)下載完整的教程示例項目代碼項目。