Skip to content

Releases: smmnn/anti-scraper

Release list

anti-scraper.php

Choose a tag to compare

@smmnn smmnn released this 22 Dec 09:03
68400f0
1, 'rate_limit' => 1, 'max_requests' => 30, 'time_window' => 60, 'disable_right_click' => 1, 'disable_text_selection' => 1, 'block_headless_browsers' => 1, 'custom_user_agents' => "example-bot\nbad-bot" ); // 仅在无配置时添加,避免覆盖已有设置 if (!get_option('anti_scraper_options')) { add_option('anti_scraper_options', $default_options); } } // 插件停用时的操作 register_deactivation_hook(__FILE__, 'anti_scraper_deactivate'); function anti_scraper_deactivate() { // 保留配置供下次使用,如需清理可取消注释 // delete_option('anti_scraper_options'); } // 添加管理菜单(中文) add_action('admin_menu', 'anti_scraper_add_admin_menu'); function anti_scraper_add_admin_menu() { add_options_page( '防爬虫设置', '防爬虫防护', 'manage_options', 'anti-scraper', 'anti_scraper_render_settings_page' ); } // 注册设置 add_action('admin_init', 'anti_scraper_register_settings'); function anti_scraper_register_settings() { register_setting('anti_scraper_group', 'anti_scraper_options', 'anti_scraper_sanitize_options'); } // 验证和清理设置 function anti_scraper_sanitize_options($input) { $output = array(); // 布尔值处理 $output['block_common_bots'] = isset($input['block_common_bots']) ? 1 : 0; $output['rate_limit'] = isset($input['rate_limit']) ? 1 : 0; $output['disable_right_click'] = isset($input['disable_right_click']) ? 1 : 0; $output['disable_text_selection'] = isset($input['disable_text_selection']) ? 1 : 0; $output['block_headless_browsers'] = isset($input['block_headless_browsers']) ? 1 : 0; // 数值范围限制 $output['max_requests'] = isset($input['max_requests']) ? intval($input['max_requests']) : 30; $output['max_requests'] = max(1, min(1000, $output['max_requests'])); $output['time_window'] = isset($input['time_window']) ? intval($input['time_window']) : 60; $output['time_window'] = max(10, min(3600, $output['time_window'])); // 文本域清洗 $output['custom_user_agents'] = isset($input['custom_user_agents']) ? sanitize_textarea_field($input['custom_user_agents']) : ''; return $output; } // 渲染设置页面(中文) function anti_scraper_render_settings_page() { if (!current_user_can('manage_options')) { wp_die(__('你没有足够的权限访问此页面。')); } $options = get_option('anti_scraper_options'); ?>
<div class="wrap">
    <h1>防爬虫防护设置</h1>
    <form method="post" action="options.php">
        <?php settings_fields('anti_scraper_group'); ?>
        
        <table class="form-table">
            <tr>
                <th scope="row"><label for="block_common_bots">阻止恶意爬虫</label></th>
                <td>
                    <input type="checkbox" id="block_common_bots" name="anti_scraper_options[block_common_bots]" 
                           value="1" <?php checked(1, $options['block_common_bots']); ?>>
                    <p class="description">仅阻止恶意爬虫(已豁免百度/谷歌/必应等合法搜索引擎)</p>
                </td>
            </tr>
            
            <tr>
                <th scope="row"><label for="block_headless_browsers">阻止无头浏览器</label></th>
                <td>
                    <input type="checkbox" id="block_headless_browsers" name="anti_scraper_options[block_headless_browsers]" 
                           value="1" <?php checked(1, $options['block_headless_browsers']); ?>>
                    <p class="description">阻止无头浏览器(如Headless Chrome),常用于批量抓取内容</p>
                </td>
            </tr>
            
            <tr>
                <th scope="row"><label for="rate_limit">启用访问频率限制</label></th>
                <td>
                    <input type="checkbox" id="rate_limit" name="anti_scraper_options[rate_limit]" 
                           value="1" <?php checked(1, $options['rate_limit']); ?>>
                    <p class="description">限制同一IP的访问频率,防止快速批量抓取</p>
                </td>
            </tr>
            
            <tr>
                <th scope="row"><label for="max_requests">最大请求数</label></th>
                <td>
                    <input type="number" id="max_requests" name="anti_scraper_options[max_requests]" 
                           value="<?php echo esc_attr($options['max_requests']); ?>" min="1" max="1000">
                    <p class="description">在指定时间窗口内允许的最大请求数(建议30-100)</p>
                </td>
            </tr>
            
            <tr>
                <th scope="row"><label for="time_window">时间窗口(秒)</label></th>
                <td>
                    <input type="number" id="time_window" name="anti_scraper_options[time_window]" 
                           value="<?php echo esc_attr($options['time_window']); ?>" min="10" max="3600">
                    <p class="description">请求计数的时间窗口(建议60-300秒)</p>
                </td>
            </tr>
            
            <tr>
                <th scope="row"><label for="disable_right_click">禁用右键菜单</label></th>
                <td>
                    <input type="checkbox" id="disable_right_click" name="anti_scraper_options[disable_right_click]" 
                           value="1" <?php checked(1, $options['disable_right_click']); ?>>
                    <p class="description">防止普通用户通过右键复制内容(可被技术手段绕过)</p>
                </td>
            </tr>
            
            <tr>
                <th scope="row"><label for="disable_text_selection">禁用文本选择</label></th>
                <td>
                    <input type="checkbox" id="disable_text_selection" name="anti_scraper_options[disable_text_selection]" 
                           value="1" <?php checked(1, $options['disable_text_selection']); ?>>
                    <p class="description">防止普通用户选择/复制文本(可被技术手段绕过)</p>
                </td>
            </tr>
            
            <tr>
                <th scope="row"><label for="custom_user_agents">自定义要阻止的User-Agent</label></th>
                <td>
                    <textarea id="custom_user_agents" name="anti_scraper_options[custom_user_agents]" 
                              rows="5" cols="50"><?php echo esc_textarea($options['custom_user_agents']); ?></textarea>
                    <p class="description">每行一个User-Agent关键词,将阻止包含这些关键词的请求</p>
                </td>
            </tr>
        </table>
        
        <?php submit_button('保存设置'); ?>
    </form>
    
    <div style="margin-top:20px; padding:10px; background:#f1f1f1; border-left:4px solid #2196F3;">
        <h3>使用提示</h3>
        <ul>
            <li>该插件仅能防护基础爬虫,无法阻止专业级爬虫(如定制化爬虫)</li>
            <li>如需配置可信代理IP段,请修改插件中 <code>anti_scraper_get_user_ip</code> 函数内的 <code>$trusted_proxies</code> 数组</li>
            <li>拦截日志可在WordPress后台「工具→站点健康→日志」中查看PHP错误日志</li>
        </ul>
    </div>
</div>
<?php

}

// 核心防护功能
add_action('init', 'anti_scraper_protect_content');
function anti_scraper_protect_content() {
// 不限制管理员
if (current_user_can('manage_options')) {
return;
}

$options = get_option('anti_scraper_options');

// 1. 阻止恶意爬虫(豁免搜索引擎)
if ($options['block_common_bots']) {
    anti_scraper_block_common_bots();
}

// 2. 阻止无头浏览器
if ($options['block_headless_browsers']) {
    anti_scraper_block_headless_browsers();
}

// 3. 阻止自定义User-Agent
if (!empty($options['custom_user_agents'])) {
    anti_scraper_block_custom_user_agents($options['custom_user_agents']);
}

// 4. 访问频率限制
if ($options['rate_limit']) {
    anti_scraper_enforce_rate_limit($options['max_requests'], $options['time_window']);
}

}

// 阻止恶意爬虫(修复:豁免合法搜索引擎)
function anti_scraper_block_common_bots() {
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';

// 合法搜索引擎爬虫白名单(核心修复:避免误封SEO)
$whitelist_bots = array(
    'BaiduSpider',    // 百度
    'Googlebot',      // 谷歌
    'Bingbot',        // 必应
    '360Spider',      // 360搜索
    'Sogou Spider',   // 搜狗
    'YisouSpider',    // 神马搜索
    'YandexBot',      // 俄罗斯Yandex
    'DuckDuckBot'     // DuckDuckGo
);

// 先检查白名单,命中则直接放行
foreach ($whitelist_bots as $white_bot) {
    if (stripos($user_agent, $white_bot) !== false) {
        return;
    }
}

// 仅拦截恶意爬虫关键词(剔除合法的bot/crawl等)
$malicious_bot_keywords = array(
    'scraper', 'grabber', 'harvest', 'parser', 'worm', 
    'linkchecker', 'webzip', 'teleport', 'httrack', 'offline'
);

foreach ($malicious_bot_keywords as $keyword) {
    if (stripos($user_agent, $keyword) !== false) {
        anti_scraper_block_request('恶意爬虫关键词匹配: ' . $keyword);
    }
}

}

// 阻止无头浏览器
function anti_scraper_block_headless_browsers() {
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
$headless_indicators = array(
'HeadlessChrome',
'PhantomJS',
'Selenium',
'webdriver',
'puppeteer'
);

foreach ($headless_indicators as $indicator) {
    if (stripos($user_agent, $indicator) !== false) {
        ...
Read more