【发布时间】:2019-06-27 07:57:43
【问题描述】:
我制作了一个爬虫应用程序,由于错误“握手警报:无法识别的名称”而导致某些网站无法连接。
我发现的大多数解决方案是禁用 SNI 扩展 (jsse.enableSNIExtension=false)。但这会给需要启用 SNI 的域带来问题。
如何仅对某些域禁用它?
为了进行爬取,我使用 Jsoup,并且因为我还使用代理,所以我在启动时添加了此代码。
private static void disableSslVerification() {
TrustManager[] trustAllCertificates = new TrustManager[] {
new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null; // Not relevant.
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
// Do nothing. Just allow them all.
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {
// Do nothing. Just allow them all.
}
}
};
HostnameVerifier trustAllHostnames = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true; // Just allow them all.
}
};
try {
System.setProperty("https.protocols", "TLSv1.2,TLSv1.1,SSLv3");
// System.setProperty("jsse.enableSNIExtension", "false");
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCertificates, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(trustAllHostnames);
}
catch (GeneralSecurityException e) {
throw new ExceptionInInitializerError(e);
}
}
如您所见,SNIextension 已被注释。我会很感激一个例子。
我要访问的网址是下一个。
https://www.ocinerioshopping.es/
【问题讨论】:
-
参见stackoverflow.com/a/14884941/139985中描述的后备策略
-
尚不清楚我是否必须为每个请求或只执行一次。另外,我第二次必须在没有主机名的情况下这样做是什么意思?我必须解析域并获取 ip 吗?
-
我的读数是 1) 对于每个失败的请求,并且 2) 是的。另外,请点击他作为示例提供的提交的链接。
-
仅仅为了提出一个请求就需要做很多工作,我还要弄清楚如何将它与 Jsoup 集成。我试试看,谢谢。
-
阅读链接答案的第一段。 Oracle 工程师认为他们所做的是正确的。期间。