5

我将阻止除大型搜索引擎之外的所有机器人。我的阻止方法之一是检查“语言”:Accept-Language:如果它没有 Accept-Language,则机器人的 IP 地址将被阻止到 2037 年。Googlebot 没有 Accept-Language,我想用 DNS 验证它抬头

<?php
gethostbyaddr($_SERVER['REMOTE_ADDR']);
?>

可以用gethostbyaddr吗,有人能通过我的“gethostbyaddr 保护”吗?

4

5 回答 5

4
function detectSearchBot($ip, $agent, &$hostname)
{
    $hostname = $ip;

    // check HTTP_USER_AGENT what not to touch gethostbyaddr in vain
    if (preg_match('/(?:google|yandex)bot/iu', $agent)) {
        // success - return host, fail - return ip or false
        $hostname = gethostbyaddr($ip);

        // https://support.google.com/webmasters/answer/80553
        if ($hostname !== false && $hostname != $ip) {
            // detect google and yandex search bots
            if (preg_match('/\.((?:google(?:bot)?|yandex)\.(?:com|ru))$/iu', $hostname)) {
                // success - return ip, fail - return hostname
                $ip = gethostbyname($hostname);

                if ($ip != $hostname) {
                    return true;
                }
            }
        }
    }

    return false;
}

在我的项目中,我使用此功能来识别 Google 和 Yandex 搜索机器人。

detectSearchBot 函数的结果是缓存。

该算法基于谷歌的推荐 - https://support.google.com/webmasters/answer/80553

于 2019-10-24T05:53:50.030 回答
3

除了克里斯蒂安的回答:

function is_valid_google_ip($ip) {
    
    $hostname = gethostbyaddr($ip); //"crawl-66-249-66-1.googlebot.com"
    
    return preg_match('/\.googlebot|google\.com$/i', $hostname);
}

function is_valid_google_request($ip=null,$agent=null){
    
    if(is_null($ip)){
        
        $ip=$_SERVER['REMOTE_ADDR'];
    }
    
    if(is_null($agent)){
        
        $agent=$_SERVER['HTTP_USER_AGENT'];
    }
    
    $is_valid_request=false;

    if (strpos($agent, 'Google')!==false && is_valid_google_ip($ip)){
        
        $is_valid_request=true;
    }
    
    return $is_valid_request;
}

笔记

有时使用$_SERVER['HTTP_X_FORWARDED_FOR']OR时$_SERVER['REMOTE_ADDR']会返回多个 IP 地址,例如“155.240.132.261, 196.250.25.120”。当此字符串作为gethostbyaddr()PHP 的参数传递时,会出现以下错误:

警告:地址不是有效的 IPv4 或 IPv6 地址...

为了解决这个问题,我使用以下代码从字符串中提取第一个 IP 地址并丢弃其余的。(如果您希望使用其他 IP,它们将位于 $ips 数组的其他元素中)。

if (strstr($remoteIP, ', ')) {
    $ips = explode(', ', $remoteIP);
    $remoteIP = $ips[0];
}

https://www.php.net/manual/en/function.gethostbyaddr.php

于 2016-05-23T09:06:11.040 回答
2
//The function
function is_google() {
    return strpos($_SERVER['HTTP_USER_AGENT'],"Googlebot");
}
于 2010-06-20T01:24:42.290 回答
2

Google 推荐的方法是进行反向 dns 查找 (gethostbyaddr) 以获取关联的主机名,然后将该名称解析为 IP (gethostbyname) 并将其与 remote_addr 进行比较(因为反向查找也可以伪造) .

但请注意,结束查找需要时间,并且会严重减慢您的网页速度(可能首先检查用户代理)。

请参阅https://webmasters.googleblog.com/2006/09/how-to-verify-googlebot.html

于 2016-05-23T09:09:47.117 回答
1

如何验证 Googlebot

于 2010-06-20T01:37:38.703 回答