GKE部署环境出现CloudFront 403错误求助(本地运行正常)
解决GKE部署后CloudFront拦截403问题
针对本地运行正常、GKE部署后遭遇CloudFront 403拦截的问题,从IP特征、爬虫指纹、请求头、网络配置几个方向逐一排查修复:
1. GKE出口IP被CloudFront拉黑
GKE节点IP属于云服务商共享IP段,极易被目标网站的CloudFront识别为爬虫IP池。
- 验证方式:在GKE节点执行以下命令,对比本地执行结果:
curl -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36" https://solved.ac/api/v3/problem/show?problemId=1000 - 解决办法:
- 配置Cloud NAT,让GKE集群使用固定出口IP,之后向目标网站申请白名单;
- 接入第三方代理IP池,在RestTemplate和Selenium中配置代理;
- 确认solved.ac官方API是否支持认证(如API Key),通过合法途径规避拦截。
2. Selenium自动化指纹被检测
仅设置User-Agent不足以隐藏自动化特征,Headless Chrome的多个属性会被反爬规则识别:
- 修复步骤:
- 更新User-Agent为最新Chrome版本的真实标识,替换老旧的Chrome 58 UA:
chromeOptions.addArguments("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36"); - 添加隐藏自动化特征的启动参数:
chromeOptions.addArguments("--disable-blink-features=AutomationControlled"); chromeOptions.addArguments("--window-size=1920,1080"); // 模拟正常窗口尺寸 - 通过CDP注入脚本,修改
navigator.webdriver属性规避JS检测:WebDriver driver = new ChromeDriver(chromeOptions); // 在页面加载前注入脚本 driver.executeCdpCommand("Page.addScriptToEvaluateOnNewDocument", ImmutableMap.of("source", "Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"));
- 更新User-Agent为最新Chrome版本的真实标识,替换老旧的Chrome 58 UA:
3. RestTemplate请求头不完整
当前RestTemplate仅配置基础字段,缺少浏览器请求的必要头信息,容易被拦截:
- 优化RestTemplate拦截器:
restTemplate.setInterceptors(Collections.singletonList( (request, body, execution) -> { HttpHeaders headers = request.getHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML)); headers.add(HttpHeaders.ACCEPT_LANGUAGE, "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7"); headers.add(HttpHeaders.USER_AGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36"); headers.add("Referer", "https://solved.ac/"); // 添加来源页标识 return execution.execute(request, body); } )); - 控制请求频率:批量请求时添加随机间隔,避免触发CloudFront速率限制:
try { Thread.sleep(new Random().nextInt(1000) + 500); // 500-1500ms随机休眠 jsonString = restTemplate.getForObject("https://solved.ac/api/v3/problem/show?problemId=" + problemId, String.class); }catch (Exception e){ e.printStackTrace(); throw new HttpResponseException("fail."); }
4. CloudFront WAF规则拦截
目标网站的CloudFront可能启用WAF,拦截无会话、无Cookie的异常请求:
- 针对RestTemplate:先请求solved.ac主页获取Cookie,再携带Cookie请求API:
// 先获取主页Cookie ResponseEntity<String> homeResponse = restTemplate.getForEntity("https://solved.ac/", String.class); String cookie = homeResponse.getHeaders().getFirst(HttpHeaders.SET_COOKIE); // 携带Cookie请求API HttpHeaders headers = new HttpHeaders(); headers.add(HttpHeaders.COOKIE, cookie); HttpEntity<Void> entity = new HttpEntity<>(headers); ResponseEntity<String> apiResponse = restTemplate.exchange( "https://solved.ac/api/v3/problem/show?problemId=" + problemId, HttpMethod.GET, entity, String.class ); jsonString = apiResponse.getBody(); - 针对Selenium:先访问solved.ac主页,再跳转到目标用户页面,让浏览器自动维护会话:
driver.get("https://solved.ac/"); sleep(1000); driver.get(SOLVED_BASE_URL + SOLVED_PROFILE + baekjoonId);
5. GKE网络配置验证
检查GKE集群的网络策略是否限制出站访问,或VPC配置导致请求源IP异常:
- 确认GKE节点出站规则允许访问
*.solved.ac及CloudFront IP段; - 若启用VPC私网,需配置Cloud NAT确保出站IP正常。
内容的提问来源于stack exchange,提问作者박우영
相关产品推荐
相关产品推荐

