[創意料理] 反爬蟲首部曲 - 如何防治初級網頁爬蟲?

爬蟲這個大多數 IT 人都聽過的名詞,有的人對它愛不釋手,有的人對它恨之入骨,在網頁上搜尋,教人當爬蟲的結果總是多過教人擋爬蟲的,技術工具本身沒有對錯,端看使用的人的心態跟手法,這篇文章來講講我如何幫客戶防治爬蟲?

何謂爬蟲?

我們先來定義一下我所理解的爬蟲 -「使用電腦程式透過網路自動化或半自動化取得特定資料」,有這樣行為的人或物,就是我所定義的爬蟲。

爬蟲對於一個網站來說,效益是極低的,不僅流量大,廣告也沒人看,底下是一張我客戶在擋掉大部分爬蟲之後流量的變化,節省了大概 50% 左右。

防治工具

底下我列舉一些在跟爬蟲對弈的過程當中使用到的工具,使用不同的開發架構、基礎設拖、框架平台,會決定我們可以使用的防治手段,多一點的工具會讓我們的防治手段多一些變化。

  • 前後端分離:把產生 HTML 內容跟商業資料分別拆開在前端及後端處理,這跟完全從後端輸出網頁內容比起來,可以讓我們多安插一些防治方法在之間的檢查點。
  • 瀏覽器:瀏覽器提供了不少的資訊,除了可以讓我們辨別爬蟲之外,還能拿來產生爬蟲無法輕鬆複製的驗證用的資訊。
  • ASP.NET Core:網站跟範例程式碼是用 ASP.NET Core 開發的,使用其他後端的程式語言的朋友,就請自行參考程式邏輯來實作。
  • FingerprintJS:它是一個產生客戶端指紋的 JavaScript 函式庫,可以產生一串幾乎唯一的識別碼,可以讓我們對單一的爬蟲,做到較為精細的防治動作。
  • JavaScript Obfuscator Tool:是一個知名的 JavaScript 程式碼混淆器,用來提高我們自行撰寫的加解密演算法被破解的難度。
  • Cloudflare:主要我們是使用它的防火牆功能,用來對一些特定的 HTTP Request Headers 進行過濾。

防治初始爬蟲

初始爬蟲是什麼?我的定義是這樣的,使用者可能對 HTTP 互動的原理不是那麼熟悉,從網路上的文章或是教學的內容,直接抄了一段範例,就開始使用 HTTP 客戶端工具爬起資料來,這樣子的爬蟲通常會漏改 User-Agent,或是特定的 Cookie 沒有塞,這種爬蟲防治起來就比較容易,我是直接在 Cloudflare 的防火牆上加入一條規則,將不符合格式的 User-Agent 或是沒有特定 Cookie 的 Request 封鎖掉。

關於目前瀏覽器的使用量排名,我們可以從 Web Browser User Agents 這個網頁找到。

如果我們沒有防火牆,也可以直接在 ASP.NET Core 中加一道 Middleware 封鎖掉這樣子的爬蟲。

public class Startup
{
    private static readonly Regex CrawlerUserAgentRegex = new Regex("chrome/|edge/|firefox/|applewebkit/", RegexOptions.IgnoreCase | RegexOptions.Compiled);
    
    // ...

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.Use(
            async (context, next) =>
                {
                    var blocked = CrawlerUserAgentRegex.Match(context.Request.Headers[HeaderNames.UserAgent]).Success;

                    blocked |= !context.Request.Cookies.ContainsKey("UID");

                    if (blocked)
                    {
                        context.Response.ContentType = "text/plain";
                        context.Response.StatusCode = 400;

                        await context.Response.WriteAsync("400 - Bad Request");
                    }
                    else
                    {
                        await next();
                    }
                });

        // ...
    }
}

初級爬蟲防治起來算是容易的,因為很輕鬆就可以辨識得出來,我們只要在防火牆上加一些過濾,或是在應用程式中加一些檢查,就可以不費吹灰之力將它們擋在外面,比較不好處理的是中級爬蟲高級爬蟲,會需要使用到其他防治工具,這個就留待之後再來講了。

相關資源

C# 指南
ASP.NET 教學
ASP.NET MVC 指引
Azure SQL Database 教學
SQL Server 教學
Xamarin.Forms 教學