Laravel有效URL仅爬虫访问时被判定为404异常如何解决
问题根因
你通过Http::get($site_url.$path)发起的测试请求默认使用Guzzle客户端UA,不会被判定为爬虫,因此返回200状态码。而真实爬虫请求携带的UA符合爬虫特征,触发了你项目中针对爬虫的拦截逻辑,所以返回404。
修复方案
- 第一步先排查项目中针对爬虫的拦截逻辑:全局搜索所有使用
new \Jenssegers\Agent\Agent()->isRobot()的代码位置,确认是否存在爬虫访问限制、路由拦截、权限校验规则,例如未对爬虫开放的路径校验、CSRF中间件未排除爬虫访问的接口等,这类逻辑是触发404的核心原因。 - 针对需要对爬虫开放的有效路径配置白名单:如果需要保留部分路径的爬虫拦截规则,可在拦截逻辑中新增路径白名单判断,命中白名单的请求即使是爬虫也直接放行,示例逻辑如下:
// 爬虫访问校验中间件示例 public function handle(Request $request, Closure $next) { $agent = new \Jenssegers\Agent\Agent(); // 自定义允许爬虫访问的路径白名单,支持通配符 $allowRobotPaths = [ '/', '/posts/*', '/pages/*', // 按需补充其他需要开放的有效路径 ]; if ($agent->isRobot() && !$request->is($allowRobotPaths)) { abort(404); } return $next($request); }
- 如果你需要对所有有效路径都开放爬虫访问,直接删除项目中所有针对爬虫的404拦截逻辑即可。
- 异常侧兜底方案:如果不想改动原有业务拦截逻辑,可以在
app/Exceptions/Handler.php中新增兜底判断,当爬虫触发404时先验证路径有效性,有效的话直接返回对应内容,避免返回404:
public function render($request, Throwable $exception) { $code = null; if(method_exists($exception, 'getStatusCode')) { $code = $exception->getStatusCode(); } $path = $request->path(); if($code === 404) { $agent = new \Jenssegers\Agent\Agent(); // 仅对爬虫请求做兜底处理 if ($agent->isRobot()) { $site_url = env('app.site_url'); $response = Http::timeout(4)->get($site_url.$path); if ($response->status() == 200) { // 直接返回对应内容和状态码 return response($response->body(), 200, $response->headers()); } } Logger::note_request_error($request, $code, $path); } return parent::render($request, $exception); }
内容的提问来源于stack exchange,提问作者Sami
相关产品推荐
相关产品推荐

