如何防止Laravel网站被HTTracks及其他软件复制
防止Laravel网站被HTTrack等网站复制软件抓取的有效措施
一、请求合法性验证(中间件实现)
HTTrack这类工具的请求头和正常浏览器差异明显,可通过自定义中间件过滤异常请求:
- 拦截可疑User-Agent
创建BlockScraper中间件:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Symfony\Component\HttpFoundation\Response; class BlockScraper { public function handle(Request $request, Closure $next): Response { $blockedAgents = ['httrack', 'wget', 'curl', 'scrapy', 'archive.org_bot']; $userAgent = strtolower($request->header('User-Agent')); foreach ($blockedAgents as $agent) { if (str_contains($userAgent, $agent)) { abort(403, 'Access Denied'); } } return $next($request); } }
将中间件注册到app/Http/Kernel.php的web中间件组,或单独绑定到需要保护的路由。
- 页面令牌验证
给每个页面生成唯一临时令牌,强制请求携带该令牌:
- 在Blade模板中插入令牌元标签:
<meta name="page-token" content="{{ session()->put('page_token', Str::random(32)) }}">
- 在中间件中验证令牌有效性:
// 在BlockScraper中间件的handle方法中追加 $pageToken = $request->header('X-Page-Token') ?? $request->get('page_token'); if (!$pageToken || $pageToken !== session('page_token')) { abort(403, 'Invalid Request'); }
前端需在AJAX等请求中自动携带令牌,正常浏览器可轻松处理,但抓取工具大概率会忽略该逻辑。
二、强化请求频率限制
借助Laravel自带的Throttle中间件,针对可疑请求收紧访问频率:
- 给目标路由组添加严格限制:
Route::middleware(['web', 'throttle:3,1'])->group(function () { // 需要保护的页面路由 });
- 自定义Throttle逻辑,对异常User-Agent单独设置更低的请求上限:
继承原生Throttle类,修改resolveRequestSignature方法,实现差异化计数。
三、动态内容渲染
HTTrack默认不执行JavaScript,可将核心内容通过JS动态渲染:
- 基础JS渲染示例:
<div id="dynamic-content"></div> <script> document.getElementById('dynamic-content').textContent = '{{ $sensitiveContent }}'; </script>
- 用Vue/React渲染核心板块:
将页面关键内容改为前端框架渲染,抓取工具仅能获取空容器,无法拿到真实内容。
四、资源访问控制
避免直接暴露静态资源路径,通过Laravel路由代理资源请求:
- 创建资源代理路由:
Route::get('protected/image/{filename}', [AssetController::class, 'serveImage'])->middleware('web');
- 控制器中验证请求并返回资源:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Storage; class AssetController extends Controller { public function serveImage(Request $request, string $filename) { // 验证用户会话有效性 if (!$request->session()->has('user_visited')) { abort(403); } $path = "protected/images/{$filename}"; if (!Storage::exists($path)) { abort(404); } return Storage::response($path); } }
这样抓取工具无法批量下载你的静态资源。
五、服务器层拦截
在Nginx或Apache配置中直接拦截抓取工具:
- Nginx配置:
server { # 其他配置 if ($http_user_agent ~* (httrack|wget|curl|scrapy)) { return 403; } }
- Apache .htaccess配置:
RewriteEngine On RewriteCond %{HTTP_USER_AGENT} ^HTTrack [NC,OR] RewriteCond %{HTTP_USER_AGENT} ^Wget [NC] RewriteRule ^ - [F,L]
六、会话与Cookie验证
强制要求访问必须携带有效会话:
- 在中间件中检查会话标识:
// 在BlockScraper中间件中追加 if (!$request->session()->exists('_token')) { abort(403, 'Session Required'); }
首次访问时Laravel会自动创建会话,抓取工具通常不会保留会话Cookie,因此会被拦截。
七、人机验证(高风险页面)
在注册、登录或内容密集页面添加reCAPTCHA:
- 安装Google reCAPTCHA包:
composer require google/recaptcha
- Blade模板中插入验证组件:
<form method="POST" action="/submit"> @csrf <div class="g-recaptcha" data-sitekey="YOUR_SITE_KEY"></div> <button type="submit">Submit</button> </form> <script src="https://www.google.com/recaptcha/api.js"></script>
- 控制器中验证:
use ReCaptcha\ReCaptcha; public function submit(Request $request) { $recaptcha = new ReCaptcha('YOUR_SECRET_KEY'); $response = $recaptcha->verify($request->input('g-recaptcha-response'), $request->ip()); if (!$response->isSuccess()) { return back()->withErrors(['captcha' => '请完成人机验证']); } // 后续业务逻辑 }
八、监控与日志记录
记录异常请求以便及时处理:
- 在中间件中添加日志记录:
// 在BlockScraper中间件检测到可疑UA时记录 logger()->warning('Scraper detected', [ 'user_agent' => $userAgent, 'ip' => $request->ip(), 'url' => $request->fullUrl() ]);
定期查看Laravel日志,发现频繁抓取的IP后,通过服务器防火墙拉黑。
内容的提问来源于stack exchange,提问作者Rajath Ramachandran
相关产品推荐
相关产品推荐

