iT邦幫忙

0

用.NET Core做網頁爬蟲抓取資料-使用HttpClicent與AngleSharp

原來文章已經不能發到鐵人賽去了...

一隻可以抓取指定網頁中資料的程式,我們習慣稱呼為爬蟲程式。聽過很多人講爬蟲程式都是使用python來撰寫。不過既然小弟現在主要已寫C#為主,當然要寫一隻運行在.NET的C#爬蟲程式。

現在微軟的.NET Core已經可以正式的運行在Linux平台上,我想寫個爬蟲希望可以同值時運行在Windows平台與Linux平台上的話,當然選擇使用.net Core而不是.net Framework。

我們用瀏覽器在點擊一個連結、或是打開一個網頁時,輸入的http://https://開頭的網址,都會發送Http請求到對應的網頁伺服器中,對方的網頁伺服器就回傳訊息給我們,其中Content欄位就是該網頁的HTML格式資料,瀏覽器解析HTML格式資料後我們便可以在瀏覽器上瀏覽這個網頁。

所以在爬蟲程式中,我們要模擬瀏覽器行為發送一個Http請求來取得網頁資料,再來就是使用AngleSharp這個套件來尋找Html的DOM元素來取得特定內容。
https://ithelp.ithome.com.tw/upload/images/20200310/20120420JEHZlhJlUE.png

關於在.NET中發送Http請求

在.NET裡面可以使用WebClient 、HttpWebRequest、HttpClient這三種類別來發送Http請求到遠端伺服器去取得資料。其中,HttpClient是.NET Framework 4.5開始加入的類別,也是NET Core中官方建議使用的類別。

我們不建議您使用 WebClient 類別來進行新的開發。 請改用 System.Net.Http.HttpClient 類別。.NET Docs:NET Core 3.1 關於 WebClient 類別
我們不建議您使用 HttpWebRequest 進行新的開發。 請改用 System.Net.Http.HttpClient 類別。.NET Docs:NET Core 3.1 關於 HttpWebRequest 類別

(雖然寫不建議,不過.NET Core 3.1裡面還是有提供這兩個類別。)

延伸閱讀:HttpClient,該 using 還是 static?

建立專案

這邊我們使用命令列來建立一個新的.NET Core console專案,並命名為Console1

dotnet new console -n  Console1

使用HttpClicent取得網頁資料

我們就依照官方的建議,使用HttpClient來取的網頁資料。

using System;
using System.Net.Http;
namespace Console1
{
    class Program
    {
        static void Main(string[] args)
        {
            HttpClient httpClient = new HttpClient();

            string url = "https://dannyliu.me";
            
            //發送請求並取得回應內容
            var responseMessage = httpClient.GetAsync(url).Result; 

            //檢查回應的伺服器狀態StatusCode是否是200 OK
            if (responseMessage.StatusCode == System.Net.HttpStatusCode.OK)
            {
                //讀取Content內容
                string responseResult = responseMessage.Content.ReadAsStringAsync().Result;

                Console.WriteLine(responseResult);
            }

            Console.ReadKey();
        }
    }
}

執行結果:
https://ithelp.ithome.com.tw/upload/images/20200310/20120420sv4FvVze1b.png

安裝AngleSharp套件

在命令列中使用dotnet add package來將AngleSharp套件加入到我們的專案

dotnet add package AngleSharp

使用AngleSharp

我們使用AngleSharp來幫我們抓HTML內的元素,會使用這一款套件的原因是因為內建了QuerySelector,使用方式跟JavaSript裡的document.QuerySelector一樣

using AngleSharp;

使用AngleSharp時的前置設定

var config = Configuration.Default;
var context = BrowsingContext.New(config);

傳入response資料

將我們用httpclient拿到的資料放入res.Content中()

//將我們用httpclient拿到的資料放入res.Content中()
var document = context.OpenAsync(res=>res.Content(responseResult)).Result;

使用QuerySelector來取得內容

//QuerySelector("head")找出<head></head>元素
var head = document.QuerySelector("head");
Console.WriteLine(head.ToHtml());
//QuerySelector(".entry-content")找出class="entry-content"的所有元素
var contents = document.QuerySelectorAll(".entry-content");

foreach(var c in contents)
{
    //取得每個元素的TextContent
    Console.WriteLine(c.TextContent);
}

執行結果:
https://ithelp.ithome.com.tw/upload/images/20200310/20120420SAzq7lKxRB.png

在GitHub看示範程式

補充:不用HttpClient,直接使用AngleSharp取得資料

//要抓取網頁資料需要WithDefaultLoader;
var config = Configuration.Default.WithDefaultLoader();
var context = BrowsingContext.New(config);
var document = context.OpenAsync("https://dannyliu.me").Result;

這是我的FB粉專,歡迎大家來按讚:FB:長庚的作業簿
還有我的Wordpress:長庚的作業簿

原文寫在用.NET Core做網頁爬蟲抓取資料-使用HttpClicent與AngleSharp---Wordpress:長庚的作業簿,本頁的程式碼已經改掉async Task Main跟await,如果要使用的話需要把專案的C#版本升到7.1以上,所以需要在專案設定檔中設定使用最新的C#版本。
例如在專案的csproj檔中加入<LangVersion>latest</LangVersion>

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
	<LangVersion>latest</LangVersion>
  </PropertyGroup>

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言