本文详解如何在 android studio 中使用 jsoup 爬取响应极慢(如 25 秒以上)的目标网站,重点解决因默认或显式 timeout 设置不当导致连接中断、文档为空的问题,并给出安全、可靠、符合 android 最佳实践的配置方案。
本文详解如何在 android studio 中使用 jsoup 爬取响应极慢(如 25 秒以上)的目标网站,重点解决因默认或显式 timeout 设置不当导致连接中断、文档为空的问题,并给出安全、可靠、符合 android 最佳实践的配置方案。
在 Android 开发中,使用 JSoup 进行网页抓取(Web Scraping)是一种轻量级且常用的技术。但当目标网站响应异常缓慢(例如你提到的 https://www.php.cn/link/06277c373fd4be8ecb96de3776dd0963 需要约 25 秒才返回完整 HTML),常规的 timeout(60000)(即 60 秒)仍可能失败——这并非因为超时值不够大,而是 JSoup 的 timeout() 方法实际控制的是 socket 连接建立 + 响应头接收阶段的总耗时,不包含完整响应体下载与解析时间。更关键的是:Android 平台对网络操作有严格限制(如主线程禁止联网),而 JSoup 的 .get() 是同步阻塞调用,若未配合异步机制,极易触发 NetworkOnMainThreadException 或 ANR。
✅ 正确做法不是盲目增大 timeout,而是将 timeout 设为 0(无限等待)并确保运行在后台线程:
// ✅ 推荐:在 WorkManager / AsyncTask(已弃用,仅作示意)/ Kotlin 协程 / 或自定义线程中执行
new Thread(() -> {
try {
// timeout(0) 表示禁用超时限制,等待服务器完成整个响应传输
Document doc = Jsoup.connect("https://www.php.cn/link/06277c373fd4be8ecb96de3776dd0963/translation.php?source=enn%20bon%20garson&lang=kreol&boutton=Translate")
.timeout(0) // 关键:启用无限等待(仅适用于可控可信源)
.userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36") // 模拟浏览器 UA
.followRedirects(true)
.get();
// 提取 body 文本(根据实际 DOM 结构调整选择器)
String translation = doc.body().text();
Log.d("JsoupResult", "Parsed: " + translation);
// ⚠️ 切记:更新 UI 必须切回主线程
runOnUiThread(() -> {
textView.setText(translation);
});
} catch (IOException e) {
Log.e("JsoupError", "Failed to fetch page", e);
runOnUiThread(() -> textView.setText("Error: " + e.getMessage()));
}
}).start();
⚠️ 重要注意事项:
- timeout(0) 仅应在明确知晓目标服务稳定性且具备容错机制的前提下使用;生产环境建议搭配 Future + ExecutorService 设置逻辑超时(如 45 秒后主动 cancel),避免线程永久挂起;
- Android 9+(API 28+)默认禁止明文 HTTP 请求,确保目标网站使用 HTTPS(本例符合);
- 必须在 AndroidManifest.xml 中声明网络权限:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
- 若页面内容由 JavaScript 动态渲染(本例为服务端直出 HTML,无需处理),JSoup 无法执行 JS;此时需考虑 WebView + JavaScriptInterface 或专用无头浏览器(如 Selenium/Playwright),但 Android 端不推荐;
- 遵循网站 robots.txt 及服务条款,高频请求可能被封禁 IP,建议添加合理延时(.maxBodySize() 也可限制响应体积防 OOM)。
? 总结:面对高延迟网站,核心是分离「网络等待策略」与「线程调度策略」——用 timeout(0) 解除 JSoup 底层 socket 超时约束,再通过 Android 标准异步机制(如 CoroutineScope(Dispatchers.IO) 或 Executors.newSingleThreadExecutor())保障主线程安全与用户体验。永远不要在主线程直接调用 .get(),也避免在不可信网络环境中无限制等待。










