使用URLConnection连接指定网站失败:Read timed out问题求助
解决URLConnection连接Zomato时的读取超时问题
问题描述
我在使用URLConnection连接指定网站(https://www.zomato.com/)时遭遇读取超时(Read timed out)错误,无法成功建立连接。我使用的代码如下:
public static void main(String[] args) throws IOException { String EngLink; URL EngUrl; URLConnection EngCon; String cookiesHeader; InputStream EngIs; BufferedReader EngBr; String line; String EngPageHtml=""; EngLink="https://www.zomato.com/"; EngUrl = new URL(EngLink); EngCon = (HttpURLConnection) EngUrl.openConnection(); EngCon.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13 (.NET CLR 3.5.30729)"); // 推测的读取逻辑 EngIs = EngCon.getInputStream(); EngBr = new BufferedReader(new InputStreamReader(EngIs)); while ((line = EngBr.readLine()) != null) { EngPageHtml += line; } EngBr.close(); EngIs.close(); }
问题分析
读取超时大概率是这几个原因:一是默认的URLConnection超时配置不合理,服务器响应慢就直接触发超时;二是Zomato的反爬机制识别出你的请求是自动化程序,故意延迟响应或者直接拒绝;三是网络波动导致数据传输中断。
解决方案
我给你几个实用的调整方案,你可以一步步尝试:
- 设置明确的超时时间
默认情况下URLConnection没有设置具体的超时阈值,很容易因为服务器响应慢而抛出超时异常。你可以手动设置连接超时和读取超时:
// 设置10秒连接超时(连不上服务器就抛出异常) EngCon.setConnectTimeout(10000); // 设置15秒读取超时(服务器没返回数据就抛出异常) EngCon.setReadTimeout(15000);
- 补充完整的请求头,模拟真实浏览器
你已经设置了User-Agent,但Zomato可能会检查更多请求头字段。补充这些字段能让你的请求更接近真实用户的浏览器请求:
EngCon.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); EngCon.setRequestProperty("Accept-Language", "en-GB,en;q=0.5"); EngCon.setRequestProperty("Referer", "https://www.google.com/"); EngCon.setRequestProperty("Connection", "keep-alive");
- 确认重定向处理
Zomato可能会返回3xx重定向响应,虽然HttpURLConnection默认会自动处理重定向,但有时候显式开启会更稳妥:
((HttpURLConnection) EngCon).setInstanceFollowRedirects(true);
- 换用更灵活的HTTP客户端(推荐)
URLConnection比较底层,处理复杂的反爬场景和请求细节不够方便。你可以试试OkHttp或者Apache HttpClient,以OkHttp为例,代码更简洁还能自动处理很多细节:
// 先引入OkHttp依赖,比如Maven: // <dependency> // <groupId>com.squareup.okhttp3</groupId> // <artifactId>okhttp</artifactId> // <version>4.12.0</version> // </dependency> OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(15, TimeUnit.SECONDS) .build(); Request request = new Request.Builder() .url("https://www.zomato.com/") .header("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13 (.NET CLR 3.5.30729)") .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") .header("Accept-Language", "en-GB,en;q=0.5") .header("Referer", "https://www.google.com/") .build(); try (Response response = client.newCall(request).execute()) { if (!response.isSuccessful()) throw new IOException("请求失败,状态码:" + response.code()); String pageHtml = response.body().string(); // 处理获取到的HTML内容 }
重要提醒
Zomato有严格的反爬机制,即使你调整了请求参数,频繁请求还是会被封禁IP。如果是做爬虫项目,建议加上随机请求间隔,使用代理IP池,并且严格遵守网站的robots.txt规则,避免触发更严厉的封禁。
内容的提问来源于stack exchange,提问作者GohanCZ
相关产品推荐
相关产品推荐

