返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >php – 如何检测伪装用户/爬虫/cURL
  • 13
分享到

php – 如何检测伪装用户/爬虫/cURL

爬虫PHPcurl 2023-07-12 10:07:46 13人浏览 佚名
摘要

问题描述其他一些网站可能会使用cURL和伪造的Http Referer复制我的网站内容。我们是否可以检测出请求是cURL而不是真正的WEB浏览器? 最佳思路没有任何完美的方法可以避免自动爬取网页。因为人可以做到的一切,机器人也可以

问题描述

其他一些网站可能会使用cURL和伪造的Http Referer复制我的网站内容。

我们是否可以检测出请求是cURL而不是真正的WEB浏览器?

 

最佳思路

没有任何完美的方法可以避免自动爬取网页。因为人可以做到的一切,机器人也可以模拟做到。但是有很多能让机器抓取变得更困难的做法,从而防止绝大部分人的专区,不过对于非常精通技术的极客效果有限。

这里介绍几种不同类型的反爬技术。


1.每个IP的会话数

如果用户每分钟使用50个新会话,则可以认为该用户可能是不处理Cookie的爬虫程序。当然,curl可以完美地管理cookie,但是如果您将其与每个会话的访问计数器结合使用(稍后说明),或者爬虫对cookie处理得不好,那么这个方法可能是有效的。

一般不太可能有50个具有相同共享连接的人会同时在您的网站上访问。如果发生这种情况,则认为是爬虫在抓取,您可以定网站页面,直到输入验证码为止。

具体步骤:

1)创建2个表:1个保存禁用的ips,1个保存ip和会话

create table if not exists sessions_per_ip (
  ip int unsigned,
  session_id varchar(32),
  creation timestamp default current_timestamp,
  primary key(ip, session_id)
);

create table if not exists banned_ips (
  ip int unsigned,
  creation timestamp default current_timestamp,
  primary key(ip)
);

2)在脚本的开头,您从两个表中删除了太旧的条目

3)接下来,您检查用户的IP是否被禁止(将标志设置为true)

4)如果没有,您可以计算出他的IP会话数

5)如果TA的会话过多,则将其插入到被禁止的表中并设置一个标志

6)如果尚未插入sessions_per_ip表,则将其ip插入

我编写了一个代码示例,以更好地显示我的想法。

<?PHP

try
{

    // Some configuration (small values for demo)
    $max_sessions = 5; // 5 sessions/ip simultaneousely allowed
    $check_duration = 30; // 30 secs max lifetime of an ip on the sessions_per_ip table
    $lock_duration = 60; // time to lock your website for this ip if max_sessions is reached

    // Mysql connection
    require_once("config.php");
    $dbh = new PDO("mysql:host={$host};dbname={$base}", $user, $passWord);
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // Delete old entries in tables
    $query = "delete from sessions_per_ip where timestampdiff(second, creation, now()) > {$check_duration}";
    $dbh->exec($query);

    $query = "delete from banned_ips where timestampdiff(second, creation, now()) > {$lock_duration}";
    $dbh->exec($query);

    // Get useful info attached to our user...
    session_start();
    $ip = ip2long($_SERVER['REMOTE_ADDR']);
    $session_id = session_id();

    // Check if IP is already banned
    $banned = false;
    $count = $dbh->query("select count(*) from banned_ips where ip = '{$ip}'")->fetchColumn();
    if ($count > 0)
    {
        $banned = true;
    }
    else
    {
        // Count entries in our db for this ip
        $query = "select count(*)  from sessions_per_ip where ip = '{$ip}'";
        $count = $dbh->query($query)->fetchColumn();
        if ($count >= $max_sessions)
        {
            // Lock website for this ip
            $query = "insert ignore into banned_ips ( ip ) values ( '{$ip}' )";
            $dbh->exec($query);
            $banned = true;
        }

        // Insert a new entry on our db if user's session is not already recorded
        $query = "insert ignore into sessions_per_ip ( ip, session_id ) values ('{$ip}', '{$session_id}')";
        $dbh->exec($query);
    }

    // At this point you have a $banned if your user is banned or not.
    // The following code will allow us to test it...

    // We do not display anything now because we'll play with sessions :
    // to make the demo more readable I prefer Going step by step like
    // this.
    ob_start();

    // Displays your current sessions
    echo "Your current sessions keys are : <br/>";
    $query = "select session_id from sessions_per_ip where ip = '{$ip}'";
    foreach ($dbh->query($query) as $row) {
        echo "{$row['session_id']}<br/>";
    }

    // Display and handle a way to create new sessions
    echo str_repeat('<br/>', 2);
    echo '<a href="' . basename(__FILE__) . '?new=1">Create a new session / reload</a>';
    if (isset($_GET['new']))
    {
        session_regenerate_id();
        session_destroy();
        header("Location: " . basename(__FILE__));
        die();
    }

    // Display if you're banned or not
    echo str_repeat('<br/>', 2);
    if ($banned)
    {
        echo '<span style="color:red;">You are banned: wait 60secs to be unbanned... a captcha must be more friendly of course!</span>';
        echo '<br/>';
        echo '<img src="http://4.bp.blogspot.com/-PezlYVgEEvg/TadW2e4OyHI/AAAAAAAAAAg/QHZPVQcBNeg/s1600/feu-rouge.png" />';
    }
    else
    {
        echo '<span style="color:blue;">You are not banned!</span>';
        echo '<br/>';
        echo '<img src="http://identityspecialist.files.wordpress.com/2010/06/traffic_light_green.png" />';
    }
    ob_end_flush();
}
catch (PDOException $e)
{
     $e->getMessage();
}

?>

2.访问计数

如果您的用户使用相同的Cookie来抓取您的页面,则可以使用其会话来阻止它。这个想法很简单:您的用户是否有可能在60秒内访问60页?

步骤:

  1. 在用户会话中创建一个数组,其中将包含每次访问时间。

  2. 删除此数组中早于X秒的访问

  3. 为实际访问添加新条目

  4. 计算此数组中的条目

  5. 如果用户访问了Y页,则禁止该用户

样例代码:

<?php

$visit_counter_pages = 5; // maximum number of pages to load
$visit_counter_secs = 10; // maximum amount of time before cleaning visits

session_start();

// initialize an array for our visit counter
if (array_key_exists('visit_counter', $_SESSION) == false)
{
    $_SESSION['visit_counter'] = array();
}

// clean old visits
foreach ($_SESSION['visit_counter'] as $key => $time)
{
    if ((time() - $time) > $visit_counter_secs) {
        unset($_SESSION['visit_counter'][$key]);
    }
}

// we add the current visit into our array
$_SESSION['visit_counter'][] = time();

// check if user has reached limit of visited pages
$banned = false;
if (count($_SESSION['visit_counter']) > $visit_counter_pages)
{
    // puts ip of our user on the same "banned table" as earlier...
    $banned = true;
}

// At this point you have a $banned if your user is banned or not.
// The following code will allow us to test it...

echo '<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/Jquery/1.6.2/jquery.min.js"></script>';

// Display counter
$count = count($_SESSION['visit_counter']);
echo "You visited {$count} pages.";
echo str_repeat('<br/>', 2);

echo <<< EOT

<a id="reload" href="#">Reload</a>

<script type="text/javascript">

  $('#reload').click(function(e) {
    e.preventDefault();
    window.location.reload();
  });

</script>

EOT;

echo str_repeat('<br/>', 2);

// Display if you're banned or not
echo str_repeat('<br/>', 2);
if ($banned)
{
    echo '<span style="color:red;">You are banned! Wait for a short while (10 secs in this demo)...</span>';
    echo '<br/>';
    echo '<img src="http://4.bp.blogspot.com/-PezlYVgEEvg/TadW2e4OyHI/AAAAAAAAAAg/QHZPVQcBNeg/s1600/feu-rouge.png" />';
}
else
{
    echo '<span style="color:blue;">You are not banned!</span>';
    echo '<br/>';
    echo '<img src="http://identityspecialist.files.wordpress.com/2010/06/traffic_light_green.png" />';
}
?>

3.图片下载

爬虫通常要在很短的时间内获取大量数据,一般不会下载页面上的图像,原因是:图像占用了太多带宽,会使抓取速度变慢。

这个方法的具体做法是:(我认为是最简洁,最容易实现的)

使用mod_rewrite将.jpg /.png /…等格式的图像文件隐藏在网页中。该图像应该在您要保护的每个页面上可用:它可能是您的网站LOGO,一般选择尺寸较小的图像(因为该图像不得缓存)。

步骤:

1. 将这些行添加到您的.htaccess中

RewriteEngine On
RewriteBase /tests/anticrawl/
RewriteRule ^logo\.jpg$ logo.php

2.使用安全性创建您的logo.php

<?php

// start session and reset counter
session_start();
$_SESSION['no_logo_count'] = 0;

// forces image to reload next time
header("Cache-Control: no-store, no-cache, must-revalidate");

// displays image
header("Content-type: image/jpg");
readfile("logo.jpg");
die();

3.在需要增加安全性的每个页面上增加no_logo_count,并检查其是否达到限制。

样例代码:

<?php

$no_logo_limit = 5; // number of allowd pages without logo

// start session and initialize
session_start();
if (array_key_exists('no_logo_count', $_SESSION) == false)
{
    $_SESSION['no_logo_count'] = 0;
}
else
{
    $_SESSION['no_logo_count']++;
}

// check if user has reached limit of "undownloaded image"
$banned = false;
if ($_SESSION['no_logo_count'] >= $no_logo_limit)
{
    // puts ip of our user on the same "banned table" as earlier...
    $banned = true;
}

// At this point you have a $banned if your user is banned or not.
// The following code will allow us to test it...

echo '<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>';

// Display counter
echo "You did not loaded image {$_SESSION['no_logo_count']} times.";
echo str_repeat('<br/>', 2);

// Display "reload" link
echo <<< EOT

<a id="reload" href="#">Reload</a>

<script type="text/javascript">

  $('#reload').click(function(e) {
    e.preventDefault();
    window.location.reload();
  });

</script>

EOT;

echo str_repeat('<br/>', 2);

// Display "show image" link : note that we're using .jpg file
echo <<< EOT

<div id="image_container">
    <a id="image_load" href="#">Load image</a>
</div>
<br/>

<script type="text/javascript">

  // On your implementation, you'llO of course use <img src="logo.jpg" />
  $('#image_load').click(function(e) {
    e.preventDefault();
    $('#image_load').html('<img src="logo.jpg" />');
  });

</script>

EOT;

// Display if you're banned or not
echo str_repeat('<br/>', 2);
if ($banned)
{
    echo '<span style="color:red;">You are banned: click on "load image" and reload...</span>';
    echo '<br/>';
    echo '<img src="http://4.bp.blogspot.com/-PezlYVgEEvg/TadW2e4OyHI/AAAAAAAAAAg/QHZPVQcBNeg/s1600/feu-rouge.png" />';
}
else
{
    echo '<span style="color:blue;">You are not banned!</span>';
    echo '<br/>';
    echo '<img src="http://identityspecialist.files.wordpress.com/2010/06/traffic_light_green.png" />';
}
?>

4.Cookie检查

您可以在javascript端创建cookie,以检查您的用户是否执行了javascript(例如,使用Curl的抓取工具不会)。

这个想法很简单:这与图像检查大致相同。

  1. 将$ _SESSION值设置为1,并在每次访问中将其递增

  2. 如果存在cookie(在JavaScript中设置),请将会话值设置为0

  3. 如果此值达到限制,择禁止用户访问

代码:

<?php

$no_cookie_limit = 5; // number of allowd pages without cookie set check

// Start session and reset counter
session_start();

if (array_key_exists('cookie_check_count', $_SESSION) == false)
{
    $_SESSION['cookie_check_count'] = 0;
}

// Initializes cookie (note: rename it to a more discrete name of course) or check cookie value
if ((array_key_exists('cookie_check', $_COOKIE) == false) || ($_COOKIE['cookie_check'] != 42))
{
    // Cookie does not exist or is incorrect...
    $_SESSION['cookie_check_count']++;
}
else
{
    // Cookie is properly set so we reset counter
    $_SESSION['cookie_check_count'] = 0;
}

// Check if user has reached limit of "cookie check"
$banned = false;
if ($_SESSION['cookie_check_count'] >= $no_cookie_limit)
{
    // puts ip of our user on the same "banned table" as earlier...
    $banned = true;
}

// At this point you have a $banned if your user is banned or not.
// The following code will allow us to test it...

echo '<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>';

// Display counter
echo "Cookie check failed {$_SESSION['cookie_check_count']} times.";
echo str_repeat('<br/>', 2);

// Display "reload" link
echo <<< EOT

<br/>
<a id="reload" href="#">Reload</a>
<br/>

<script type="text/javascript">

  $('#reload').click(function(e) {
    e.preventDefault();
    window.location.reload();
  });

</script>

EOT;

// Display "set cookie" link
echo <<< EOT

<br/>
<a id="cookie_link" href="#">Set cookie</a>
<br/>

<script type="text/javascript">

  // On your implementation, you'll of course put the cookie set on a $(document).ready()
  $('#cookie_link').click(function(e) {
    e.preventDefault();
    var expires = new Date();
    expires.setTime(new Date().getTime() + 3600000);
    document.cookie="cookie_check=42;expires=" + expires.toGMTString();
  });

</script>
EOT;


// Display "unset cookie" link
echo <<< EOT

<br/>
<a id="unset_cookie" href="#">Unset cookie</a>
<br/>

<script type="text/javascript">

  // On your implementation, you'll of course put the cookie set on a $(document).ready()
  $('#unset_cookie').click(function(e) {
    e.preventDefault();
    document.cookie="cookie_check=;expires=Thu, 01 Jan 1970 00:00:01 GMT";
  });

</script>
EOT;

// Display if you're banned or not
echo str_repeat('<br/>', 2);
if ($banned)
{
    echo '<span style="color:red;">You are banned: click on "Set cookie" and reload...</span>';
    echo '<br/>';
    echo '<img src="http://4.bp.blogspot.com/-PezlYVgEEvg/TadW2e4OyHI/AAAAAAAAAAg/QHZPVQcBNeg/s1600/feu-rouge.png" />';
}
else
{
    echo '<span style="color:blue;">You are not banned!</span>';
    echo '<br/>';
    echo '<img src="http://identityspecialist.files.wordpress.com/2010/06/traffic_light_green.png" />';
}

5.防止代理

我们可以在网上找到有关不同种类的代理的一些信息:

  • 普通代理显示有关用户连接(尤其是其IP)的信息。 (“nORMal” proxy)

  • 匿名代理不显示IP,但在标头上提供有关代理使用的信息。(anonymous proxy)

  • 高度匿名代理不显示用户IP,也不显示浏览器可能无法发送的任何信息。(high-anonyous proxy)

发现连接任何网站的代理很容易,但是很难发现high-anonymous代理。

一些$ _SERVER变量可能包含密钥,特别是如果您的用户位于代理之后(详尽列表来自this question):

  • CLIENT_IP

  • FORWARDED

  • FORWARDED_FOR

  • FORWARDED_FOR_IP

  • HTTP_CLIENT_IP

  • HTTP_FORWARDED

  • HTTP_FORWARDED_FOR

  • HTTP_FORWARDED_FOR_IP

  • HTTP_PC_REMOTE_ADDR

  • HTTP_PROXY_CONNECTION’

  • HTTP_VIA

  • HTTP_X_FORWARDED

  • HTTP_X_FORWARDED_FOR

  • HTTP_X_FORWARDED_FOR_IP

  • HTTP_X_IMFORWARDS

  • HTTP_XROXY_CONNECTION

  • VIA

  • X_FORWARDED

  • X_FORWARDED_FOR

如果您检测到$_SERVER变量中有上述字段,就可以为反爬制定相应的反代理安全策略。


结论

综上,有很多方法可以检测到您网站上的爬虫行为。但是,需要精确地了解网站的使用方式,从而您的安全策略误伤正常用户。

 

参考资料

 

--结束END--

本文标题: php – 如何检测伪装用户/爬虫/cURL

本文链接: https://lsjlt.com/news/361059.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • php – 如何检测伪装用户/爬虫/cURL
    问题描述其他一些网站可能会使用cURL和伪造的http Referer复制我的网站内容。我们是否可以检测出请求是cURL而不是真正的Web浏览器? 最佳思路没有任何完美的方法可以避免自动爬取网页。因为人可以做到的一切,机器人也可以...
    99+
    2023-07-12
    爬虫 PHP curl
  • php – 如何检测伪装用户/爬虫/cURL
    问题描述其他一些网站可能会使用cURL和伪造的http Referer复制我的网站内容。我们是否可以检测出请求是cURL而不是真正的Web浏览器? 最佳思路没有任何完美的方法可以避免自动爬取网页。因为人可以做到的一切,机器人也可以...
    99+
    2024-03-05
    curl php 伪装用户 反爬 爬虫检测
  • python爬虫如何伪装
    Python爬虫可以通过以下几种方式来伪装自己,以避免被网站封禁或限制访问:1. 设置User-Agent:在请求头中设置User-...
    99+
    2023-08-17
    python
  • python网络爬虫之如何伪装逃过反爬虫程序的方法
    有的时候,我们本来写得好好的爬虫代码,之前还运行得Ok, 一下子突然报错了。 报错信息如下: Http 800 Internal internet error 这是因为你的对象网站设置了反爬虫程序,如果用现...
    99+
    2022-06-04
    爬虫 逃过 程序
  • php如何应用Ajax技术检测用户名
    这篇文章主要介绍php如何应用Ajax技术检测用户名,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1.搭建Ajax开发框架,代码如下<script language=...
    99+
    2024-04-02
  • python爬虫时如何知道是否代理ip伪装成功
    有时候我们的爬虫程序添加了代理,但是我们不知道程序是否获取到了ip,尤其是动态转发模式的,这时候就需要进行检测了,以下是一种代理是否伪装成功的检测方式,这里推介使用亿牛云提供的代码示例。Python¶requests #!&nbs...
    99+
    2023-06-02
  • 在PHP中如何使用CURL方法伪造referer地址
    小编给大家分享一下在PHP中如何使用CURL方法伪造referer地址,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!CURL$u...
    99+
    2024-04-02
  • 如何检测php是否安装成功
    小编给大家分享一下如何检测php是否安装成功,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!php有什么用php是一个嵌套的缩写名称,是英文超级文本预处理语言,它的语法混合了C、Java、Perl以及php自创新的语法,主要...
    99+
    2023-06-14
  • 如何使用PHP编写爬虫程序
    在互联网时代,信息就像一条无休无止的河流,源源不断地涌出来。有时候我们需要从Web上抓取一些数据,以便分析或者做其他用途。这时候,爬虫程序就显得尤为重要。爬虫程序,顾名思义,就是用来自动化地获取Web页面内容的程序。 作为一门广泛应用的编程...
    99+
    2023-09-03
    php 爬虫 开发语言
  • python如何伪装用户真实信息
    小编给大家分享一下python如何伪装用户真实信息,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!伪装用户真实信息有些网页是需要登...
    99+
    2024-04-02
  • AJAX如何检测用户名是否存在
    小编给大家分享一下AJAX如何检测用户名是否存在,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!vscode:index:<!DOCTYPE htm...
    99+
    2023-06-08
  • 如何使用PHP蜘蛛爬虫框架来爬取数据
    这篇文章主要介绍了如何使用PHP蜘蛛爬虫框架来爬取数据的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇如何使用PHP蜘蛛爬虫框架来爬取数据文章都会有所收获,下面我们一起来看看吧。...
    99+
    2024-04-02
  • ajax如何检测用户名是否被占用
    这篇文章主要讲解了“ajax如何检测用户名是否被占用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“ajax如何检测用户名是否被占用”吧!代码如下://检测用...
    99+
    2024-04-02
  • 如何利用Ajax检测用户名是否被占用
    小编给大家分享一下如何利用Ajax检测用户名是否被占用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!采用Ajax实现用户名验证使用jQuery给出提示信息用户注册...
    99+
    2023-06-08
  • 如何应用AJAX进行注册用户即时检测
    本篇文章为大家展示了如何应用AJAX进行注册用户即时检测,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。 AJAX的无刷新机制使得在注册...
    99+
    2024-04-02
  • 如何用PHP实现微信域名检测
    本篇内容介绍了“如何用PHP实现微信域名检测”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!微信防红接口调用也很简单,接口地址:https:/...
    99+
    2023-06-03
  • AJAX如何实现无刷新检测用户名功能
    这篇文章将为大家详细讲解有关AJAX如何实现无刷新检测用户名功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。先来看看原理图register.php<!DOCTYPE html>&l...
    99+
    2023-06-08
  • javascript如何实现浏览器用户代理检测脚本
    这篇文章给大家分享的是有关javascript如何实现浏览器用户代理检测脚本的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。以下是完整的用户代理字符串检测脚本,包括检测呈现引擎、平...
    99+
    2024-04-02
  • python如何使用pywinauto驱动微信客户端实现公众号爬虫
    这篇文章主要介绍了python如何使用pywinauto驱动微信客户端实现公众号爬虫,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。pywinauto简介pywinauto是一...
    99+
    2023-06-15
  • 如何检测小程序当前用户登录态是否有效
    这篇“如何检测小程序当前用户登录态是否有效”除了程序员外大部分人都不太理解,今天小编为了让大家更加理解“如何检测小程序当前用户登录态是否有效”,给大家总结了以下内容,具有一定借鉴价值,内容详细步骤清晰,细节处理妥当,希望大家通过这篇文章有所...
    99+
    2023-06-26
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作