
本文讲解如何在 Android Studio 中使用 JSOUP 抓取响应缓慢的网站(如 translatekreol.mu),重点解决因服务器响应延迟导致 Jsoup.connect().get() 阻塞或失败的问题,核心方案是合理设置连接与读取超时,尤其推荐使用 timeout(0) 启用无限等待。
本文讲解如何在 android studio 中使用 jsoup 抓取响应缓慢的网站(如 translatekreol.mu),重点解决因服务器响应延迟导致 `jsoup.connect().get()` 阻塞或失败的问题,核心方案是合理设置连接与读取超时,尤其推荐使用 `timeout(0)` 启用无限等待。
在 Android 开发中,使用 JSOUP 进行网页抓取(Web Scraping)是一种轻量且高效的方式。但当目标网站响应极慢(例如需 25 秒以上才返回 HTML)、存在服务端延迟、或依赖动态渲染逻辑时,JSOUP 默认的超时机制(通常为 3 秒)极易触发 java.net.SocketTimeoutException 或静默失败,导致 Document doc 为空或请求中断——正如你在抓取 https://translatekreol.mu/translation.php?... 时所遇到的问题。
关键在于:JSOUP 的 .timeout(int millis) 方法同时控制连接超时(connection timeout)和读取超时(read timeout)。即使你设置了 timeout(60000)(60 秒),若服务器在建立 TCP 连接后迟迟不发送响应体(如后端翻译逻辑耗时过长),JSOUP 仍可能在读取阶段提前终止。
✅ 正确做法是:显式分离连接与读取超时,并对高延迟站点启用无限读取等待:
try {
// 推荐:分别设置连接超时(合理值)与读取超时(0 = 无限等待)
Document doc = Jsoup.connect("https://translatekreol.mu/translation.php?&source=enn%20bon%20garson&lang=kreol&boutton=Translate")
.userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36") // 模拟浏览器 UA
.timeout(10_000) // 连接超时设为 10 秒(足够建立连接)
.maxBodySize(0) // 禁用响应体大小限制(避免因内容大被截断)
.get();
// 提取 body 内容(该站点结果直接在 中)
String translation = doc.body().text();
Log.d("JSOUP", "Result: " + translation);
} catch (IOException e) {
Log.e("JSOUP", "Fetch failed", e);
}
⚠️ 重要注意事项:
- timeout(0) 的含义:它表示「无限超时」,即 JSOUP 将持续等待直到数据到达或网络异常中断。这适用于你已知目标服务必然响应但极慢的场景(如该克里奥尔语翻译站),但不可滥用在不可控公网环境,否则可能导致主线程卡死(Android 中务必在后台线程执行!)。
- 必须运行在非 UI 线程:JSOUP 是阻塞式 HTTP 客户端,绝对禁止在主线程调用 .get() 或 .post(),否则触发 NetworkOnMainThreadException。请使用 Thread、AsyncTask(已弃用,仅作兼容参考)、Executors 或现代方案如 Kotlin Coroutines + withContext(Dispatchers.IO)。
- 添加 User-Agent:部分网站(包括该翻译站)会拒绝无 UA 的请求,返回空页或 403。设置合理 UA 可显著提升成功率。
- 检查 HTTPS 证书与 TLS 兼容性:老旧 Android 版本(API
- 备用方案考虑:若页面实际依赖 JavaScript 渲染(尽管本例是服务端 PHP 输出),JSOUP 无法执行 JS,此时应改用 WebView + JavaScriptInterface 或专用无头浏览器(如 Selenium Grid + Appium 不适用移动端;更现实的是服务端代理解析)。
总结:面对高延迟 Web API,不要盲目增大单一 timeout() 值;而是采用「有限连接超时 + 无限读取等待」策略,并严格保障网络操作在后台线程执行。配合 UA 设置与异常处理,即可稳定抓取类似 translatekreol.mu 这类响应缓慢但结构简单的服务端渲染页面。










