Jsoup使用带身份验证的代理时出现connect timed out超时问题求助
问题根因定位
你已经排查到原生java.net.Proxy搭配HttpURLConnection也出现连接超时,说明该问题和Jsoup本身无关,属于JDK层面的代理连通或认证配置问题。Selenium自身实现了代理认证逻辑,不依赖JDK默认的Authenticator,所以出现Selenium代理可用、JDK代理不可用的差异。
可能原因及解决方案
1. JDK默认禁用了HTTPS隧道代理的Basic认证
JDK 8u111及之后的版本默认禁用了HTTPS隧道代理的Basic认证方案,这是最常见的近期代理突然失效的原因,刚好符合你“此前代码正常、近期新增错误”的特征。
解决方案:在代码初始化阶段添加如下系统属性配置:
System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "") System.setProperty("jdk.https.auth.tunneling.disabledSchemes", "")
2. ProxyAuthenticator实现不符合要求
JDK的Authenticator需要正确重写getPasswordAuthentication方法才能返回代理认证凭证,常见的错误是没有处理请求类型为代理的场景。
解决方案:确认ProxyAuthenticator的实现逻辑如下:
class ProxyAuthenticator extends Authenticator { override def getPasswordAuthentication: PasswordAuthentication = { if (getRequestorType == RequestorType.PROXY) { return new PasswordAuthentication("你的代理用户名", "你的代理密码".toCharArray) } null } }
3. InetSocketAddress构造错误
getInetSocketAddress方法如果是通过域名构造的实例,可能存在域名解析失效、解析结果不正确的问题,也有可能误用了InetSocketAddress.createUnresolved方法构造了未解析的地址。
解决方案:
- 先通过命令行验证代理本身连通性:
curl -x 代理IP:代理端口 -U 用户名:密码 https://www.baidu.com,确认代理服务本身可用 - 硬编码代理IP和端口构造
InetSocketAddress,避免解析问题:
val proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("你的代理IP", 代理端口))
4. 全局代理配置覆盖了手动传入的Proxy对象
如果环境中存在http.proxyHost、https.proxyPort等全局系统代理配置,或者其他组件修改了默认的代理选择器,会导致手动传入的Proxy对象不生效。
解决方案:在创建连接前清空相关系统属性:
System.clearProperty("http.proxyHost") System.clearProperty("http.proxyPort") System.clearProperty("https.proxyHost") System.clearProperty("https.proxyPort")
验证步骤
先单独运行原生HttpURLConnection的测试代码,完成上述配置修改后如果能正常返回结果,再将配置同步到Jsoup的调用逻辑中即可,Jsoup的代理实现完全基于JDK原生的HttpURLConnection,原生逻辑通顺后Jsoup自然可以正常使用代理。
内容的提问来源于stack exchange,提问作者Myriam K.

