go-web-utils
uautil

IsBot

检测 HTTP 请求是否来自机器人

IsBot

检测 HTTP 请求是否来自机器人。

函数签名

func IsBot(r *http.Request, allowLegitimate bool) bool

参数

  • r (*http.Request): HTTP 请求对象
  • allowLegitimate (bool): 是否允许合法的搜索引擎爬虫
    • true: 允许合法搜索引擎(Google、Bing 等),仅拦截恶意机器人
    • false: 拦截所有机器人,包括搜索引擎

返回值

  • bool: 如果是机器人返回 true,否则返回 false

使用示例

拦截所有机器人

package main

import (
    "net/http"
    "github.com/woodchen-ink/go-web-utils/uautil"
)

func handler(w http.ResponseWriter, r *http.Request) {
    // 拦截所有机器人
    if uautil.IsBot(r, false) {
        http.Error(w, "Bot access denied", http.StatusForbidden)
        return
    }

    w.Write([]byte("Welcome, human!"))
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

SEO 友好模式(允许搜索引擎)

func handler(w http.ResponseWriter, r *http.Request) {
    // 允许合法搜索引擎,但拦截恶意爬虫
    if uautil.IsBot(r, true) {
        http.Error(w, "Malicious bot detected", http.StatusForbidden)
        return
    }

    w.Write([]byte("Welcome!"))
}

记录机器人访问

func handler(w http.ResponseWriter, r *http.Request) {
    isBot := uautil.IsBot(r, true)

    if isBot {
        // 记录恶意机器人访问
        log.Printf("Blocked bot: %s from %s",
            r.UserAgent(),
            r.RemoteAddr)

        http.Error(w, "Access denied", http.StatusForbidden)
        return
    }

    // 正常处理
    w.Write([]byte("Success"))
}

检测逻辑

  1. 空 User-Agent: 如果请求没有 User-Agent,视为机器人
  2. 合法爬虫检查 (当 allowLegitimate=true 时):
    • 先检查是否匹配合法搜索引擎爬虫特征
    • 如果是合法爬虫,返回 false(不拦截)
  3. 机器人特征匹配:
    • 检查 User-Agent 是否包含常见机器人特征
    • 匹配任一特征则返回 true

内置特征列表

恶意机器人特征

  • python-requests, python-urllib
  • curl, wget
  • java/, okhttp, go-http-client
  • scrapy, selenium, phantomjs
  • nmap, masscan, nikto, sqlmap
  • bot, crawler, spider, scraper

合法搜索引擎特征

  • googlebot (Google)
  • bingbot (Bing)
  • baiduspider (百度)
  • slurp (Yahoo)
  • duckduckbot (DuckDuckGo)
  • facebookexternalhit, twitterbot, linkedinbot

性能说明

  • 时间复杂度: O(n),n 为特征列表长度
  • 空间复杂度: O(1)
  • 适用于高并发场景

另请参阅