You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java读取Groupon特定站点标题遇403/SocketTimeoutException,求模拟浏览器方案

解决Java程序访问Groupon站点时的403/超时问题

我碰到过不少类似的反爬拦截问题,Groupon的反机制确实做得比较严,光改User-Agent肯定不够。咱们一步步拆解问题,看看怎么解决:

1. 完整复刻浏览器的请求头

服务器会校验请求头的完整性,光一个User-Agent远远不够。你可以打开浏览器的开发者工具(按F12,切换到Network标签),访问目标页面,复制浏览器发送的所有关键请求头,在Java里逐个设置。比如Chrome发送的典型请求头包括:

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://www.groupon.pl/
Connection: keep-alive
Upgrade-Insecure-Requests: 1

这些字段里,Accept、Accept-Encoding、Referer都是服务器重点检查的,缺了任何一个都可能触发拦截。

2. 处理Cookie和会话

浏览器第一次访问Groupon主页时,服务器会下发一堆Cookie(比如会话ID、跟踪标识),后续请求必须带上这些Cookie才能被认为是合法的会话。在Java里,你可以用CookieManager来自动保存和复用Cookie:

CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
// 先请求Groupon主页获取Cookie,再请求目标酒店页面
HttpClient client = HttpClient.newHttpClient();
client.send(HttpRequest.newBuilder(URI.create("https://www.groupon.pl/")).GET().build(), HttpResponse.BodyHandlers.discarding());
// 再发送目标页面请求
HttpResponse<String> response = client.send(HttpRequest.newBuilder(URI.create("https://www.groupon.pl/deals/ga-hotel-alpin-17")).GET()
        .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36")
        // 加上其他复制的请求头
        .build(), HttpResponse.BodyHandlers.ofString());

这样就能模拟浏览器的会话流程,避免被服务器识别为无会话的爬虫。

3. 匹配浏览器的TLS版本和HTTP协议

有些站点会拒绝旧版本的TLS协议,Java默认的TLS配置可能不够新。你可以强制Java使用TLS 1.2或1.3:

System.setProperty("https.protocols", "TLSv1.2,TLSv1.3");

另外,现代浏览器大多用HTTP/2,而Java的旧版HttpClient可能默认用HTTP/1.1。从Java 11开始,HttpClient支持HTTP/2,你可以启用它:

HttpClient client = HttpClient.newBuilder()
        .version(HttpClient.Version.HTTP_2)
        .build();

这能让你的请求更接近真实浏览器的行为。

4. 控制请求频率,模拟人类浏览节奏

服务器会检测短时间内的高频请求,直接触发超时或403。你需要在请求之间加入合理的延迟,比如1-3秒的随机间隔:

// 生成1到3秒的随机延迟
long delay = (long) (Math.random() * 2000 + 1000);
Thread.sleep(delay);

不要连续发送请求,分批次执行,避免被服务器的频率检测机制盯上。

5. 终极方案:使用无头浏览器

如果以上方法都不管用,那就直接用无头浏览器来模拟真实的浏览器环境。比如用Selenium配合ChromeDriver,它会完全模拟浏览器的渲染、JS执行、Cookie处理等行为:

ChromeOptions options = new ChromeOptions();
options.addArguments("--headless=new"); // 无头模式,不弹出浏览器窗口
options.addArguments("--disable-blink-features=AutomationControlled"); // 避免被检测为自动化工具
WebDriver driver = new ChromeDriver(options);
driver.get("https://www.groupon.pl/deals/ga-hotel-alpin-17");
String title = driver.getTitle();
System.out.println(title);
driver.quit();

注意要下载和你的Chrome浏览器版本匹配的ChromeDriver,否则会报错。

为什么wget能成功?

wget默认的请求头可能刚好符合服务器的宽松校验,而且它的请求模式比较简单,没有触发反爬规则。而Java程序的默认请求头(比如空的Accept、旧的User-Agent)太容易被识别为非浏览器请求,哪怕你补了User-Agent,其他关键字段缺失还是会被拦截。

内容的提问来源于stack exchange,提问作者supertramp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:49:38