使用 JSOUP 抓取网页并给出 SSL 错误。这是站点特定问题吗? (JSOUP 适用于其他网站)
Scraping A Webpage With JSOUP and Given An SSL Error. Is This A Site Specific Issue? (JSOUP Works On Other Websites)
使用 JSOUP 抓取网页并给出 SSL 错误。这是站点特定问题吗? (JSOUP 适用于其他网站)
我正在尝试运行刮擦,我一直运行这样刮擦,但是这次失败了。
一般我都是用jsoup连接一个网页,然后在页面上抓取我想要的东西。这个似乎在尝试进行 ssl 握手或其他操作,但失败了。
我发现 this page 有类似的问题,但是,我认为 op 在所有 jsoup 抓取上都有这个问题,我的问题是针对这个网站的。
https://www.strack.de/de/shop/?idm=1162&d=1&idmp=94&spb=MTQ7NzQ7MTI0OzEyMzY7
我在这个网站上尝试了多个页面,但都有同样的问题。但是,我尝试过的所有其他网站根本没有这个问题并且可以正常抓取。
我尝试安装最新版本的 java 并重新启动电脑,这并没有导致 ssl 连接成功。我还尝试进入 Firefox 并下载认证。这似乎与答案中描述的路径不同。
"more info" > "security" > "show certificate" > "details" > "export.."
我认为这个问题可能是由另一个问题引起的,因为抓取工具在其他网站上运行良好。这就是为什么我将其创建为一个单独的问题而不是对该问题的评论。
这是我尝试下载证书时发生的情况。
没有显示证书,而是查看证书,它没有详细信息选项,也没有导出选项。
Trying to get the .cert file, no prompt
我是不是做错了什么导致握手,或者这是某种不允许在这个网站上抓取的功能?我试图从这个网页上刮掉定价:
https://www.strack.de/de/shop/?idm=1162&d=1&idmp=94&spb=MTQ7NzQ7MTI0OzEyMzY7
我使用 JSOUP 尝试抓取此页面。
它给了我一个错误。当我用谷歌搜索时,它似乎是人们在尝试连接到服务器时遇到的错误。
它给了我这个错误:
Exception in thread "main" javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to
find valid certification path to requested target at
sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at
sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949) at
sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302) at
sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296) at
sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509)
at
sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979) at
sun.security.ssl.Handshaker.process_record(Handshaker.java:914) at
sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062) at
sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
at
sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
at
sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at
sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
at
sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at
sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153)
at
org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:732)
at
org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:707)
at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:297)
at org.jsoup.helper.HttpConnection.get(HttpConnection.java:286) at
scrapetestforstack.de.ScrapeTestForStackDe.main(ScrapeTestForStackDe.java:81)
Caused by: sun.security.validator.ValidatorException: PKIX path
building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to
find valid certification path to requested target at
sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387)
at
sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
at sun.security.validator.Validator.validate(Validator.java:260) at
sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
at
sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
at
sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
at
sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1491)
... 15 more Caused by:
sun.security.provider.certpath.SunCertPathBuilderException: unable to
find valid certification path to requested target at
sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
at
sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
at
sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
... 21 more
C:\Users\LeonardDME\AppData\Local\NetBeans\Cache.2\executor-snippets\run.xml:53:
Java returned: 1 BUILD FAILED (total time: 0 seconds)
这是我正在尝试执行的代码。
//第 3 阶段为 UrlsURL 抓取
文档 doc = Jsoup.connect(URL).get();
title = doc.title();
TitleFixer = title.replaceAll(" ", "");
title = TitleFixer.replaceAll("|", "");
TitleFixer = title.replaceAll("|", "");
title = TitleFixer.replaceAll(";", "");
//Set file writing stuff 1
GimmeAName = ("C:\Users\LeonardDME\Documents\NetBeansProjects\ScrapeTestForStackDe\Urls\" + title + ".csv");
File f = new File(GimmeAName);
FileWriter fw = new FileWriter(f);
PrintWriter out = new PrintWriter(fw);
StuffToWrite = URLArray[counter];
// fetch the document over HTTP
Elements spangrabbers = doc.getElementsByClass("art_orginal_preis142790");
for (Element spangrab : spangrabbers)
{
//System.out.println("New Span: ");
//System.out.println(spangrab);
holder2 = spangrab.text();
//System.out.println(holder2);
SpanHolderArray[SpanHolderCounter] = holder2;
SpanHolderCounter++;
}
// get all links in page
Elements links = doc.select("a[href]");
for (Element link : links) {
// get the value from the href attribute
checker = link.attr("href");
if (checker.contains("http"))
{
}
else if(checker.contains("javascript"))
{
}
else if(checker.contains("style"))
{
}
else
{
counter++;
if(LinkContorter == null && LinkContorter.isEmpty())
{
//do nothing
}
else
{
System.out.println(LinkContorter);
out.print(LinkContorter);
out.print(",");
out.print("\n");
//Flush the output to the file
out.flush();
}
}
}
System.out.println(counter);
//Close the Print Writer
out.close();
//Close the File Writer
fw.close();
有没有可能你们中的一些人可以尝试抓取这个网站,看看你们是否得到了和我一样的结果?我怀疑可能有一些防止抓取的安全措施,但是,我不想放弃这个任务,除非我知道情况确实如此。几个月前的二月或三月,我也曾经毫无问题地抓取过同一个网站。
如果您不发送任何敏感数据,您可以稍微作弊并配置您自己的 TrustManger 以接受所有内容。
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
}
} };
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
现在它将用于每个连接,因此不推荐使用。相反,您可以注释掉最后一行,并通过指定 SSLSocketFactory 使 jsoup 仅将其用于单个连接:
// HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); // not needed anymore
Document doc = Jsoup.connect(URL)
.sslSocketFactory(sc.getSocketFactory())
.get();
虽然 Firefox 显示此服务器使用的证书确实使用中间 CA Sectigo RSA Domain Validation Secure Server CA
和根 CA USERTrust RSA Certification Authority
进行验证,但服务器仅发送叶证书而不发送中间证书 'chain' 标准要求的证书。
您可以通过查看 SSLLabs test report; notice the orange warning in the summary and this near the bottom of the cert details box 来了解这一点。或者,如果您拥有(或获得)OpenSSL openssl s_client -connect www.strack.de:443 -showcerts
(如今许多服务器需要 SNI,对于低于 1.1.1 的 OpenSSL 发送 SNI,您需要添加 -servername $host
而不是 this 服务器),或者因为你有 Java keytool -printcert -sslserver www.strack.de
.
省略所需的链证书是懒得阅读文档的服务器管理员的一个常见错误,因为如果他们只使用一两个浏览器进行测试,他们不会注意到这个错误——浏览器通常可以解决缺少的链证书,但大多数其他软件,包括 Java,默认情况下不能或不能。它不太可能被用作故意的反抓取措施,因为它很容易被绕过,请参阅下一页,但它确实表明服务器管理员没有实际目标或兴趣 支持或协助抓取。
而不是忽略 所有 证书问题,因为 您可以通过获取链证书来解决这个问题——例如通过从 Firefox 导出或通过获取证书 http://crt.sectigo.com/SectigoRSADomainValidationSecureServerCA.crt
中的 caIssuer link(在 SSLLabs 报告或 keytool -printcert
解码中显示,或者如果您 运行 openssl s_client
输出到 openssl x509 -noout -text
) -- 并将其添加到您的信任库(默认情况下文件 $JREDIR/lib/security/cacerts
或 jssecacerts
除非您使用 sysprop 或代码更改它)。
(已添加)Re Firefox,您已经发现 UI 在您 link 编辑的 Q 之后的几年中发生了细微变化:您现在单击挂锁,然后单击右箭头、更多信息、查看证书。要导出特定证书,请单击“Sectigo RSA ...”选项卡并向下滚动到一半:
然后单击“PEM(cert)”并保存在适当的位置。
您也可以将此问题报告给站点管理员或所有者。他们是否会关心你或一般的非浏览器访问我不知道。
使用 JSOUP 抓取网页并给出 SSL 错误。这是站点特定问题吗? (JSOUP 适用于其他网站)
我正在尝试运行刮擦,我一直运行这样刮擦,但是这次失败了。 一般我都是用jsoup连接一个网页,然后在页面上抓取我想要的东西。这个似乎在尝试进行 ssl 握手或其他操作,但失败了。
我发现 this page 有类似的问题,但是,我认为 op 在所有 jsoup 抓取上都有这个问题,我的问题是针对这个网站的。 https://www.strack.de/de/shop/?idm=1162&d=1&idmp=94&spb=MTQ7NzQ7MTI0OzEyMzY7 我在这个网站上尝试了多个页面,但都有同样的问题。但是,我尝试过的所有其他网站根本没有这个问题并且可以正常抓取。
我尝试安装最新版本的 java 并重新启动电脑,这并没有导致 ssl 连接成功。我还尝试进入 Firefox 并下载认证。这似乎与答案中描述的路径不同。
"more info" > "security" > "show certificate" > "details" > "export.."
我认为这个问题可能是由另一个问题引起的,因为抓取工具在其他网站上运行良好。这就是为什么我将其创建为一个单独的问题而不是对该问题的评论。
这是我尝试下载证书时发生的情况。 没有显示证书,而是查看证书,它没有详细信息选项,也没有导出选项。 Trying to get the .cert file, no prompt
我是不是做错了什么导致握手,或者这是某种不允许在这个网站上抓取的功能?我试图从这个网页上刮掉定价: https://www.strack.de/de/shop/?idm=1162&d=1&idmp=94&spb=MTQ7NzQ7MTI0OzEyMzY7
我使用 JSOUP 尝试抓取此页面。 它给了我一个错误。当我用谷歌搜索时,它似乎是人们在尝试连接到服务器时遇到的错误。
它给了我这个错误:
Exception in thread "main" javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979) at sun.security.ssl.Handshaker.process_record(Handshaker.java:914) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387) at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185) at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153) at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:732) at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:707) at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:297) at org.jsoup.helper.HttpConnection.get(HttpConnection.java:286) at scrapetestforstack.de.ScrapeTestForStackDe.main(ScrapeTestForStackDe.java:81) Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387) at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292) at sun.security.validator.Validator.validate(Validator.java:260) at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324) at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229) at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1491) ... 15 more Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141) at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126) at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280) at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382) ... 21 more C:\Users\LeonardDME\AppData\Local\NetBeans\Cache.2\executor-snippets\run.xml:53: Java returned: 1 BUILD FAILED (total time: 0 seconds)
这是我正在尝试执行的代码。
//第 3 阶段为 UrlsURL 抓取
文档 doc = Jsoup.connect(URL).get();
title = doc.title();
TitleFixer = title.replaceAll(" ", "");
title = TitleFixer.replaceAll("|", "");
TitleFixer = title.replaceAll("|", "");
title = TitleFixer.replaceAll(";", "");
//Set file writing stuff 1
GimmeAName = ("C:\Users\LeonardDME\Documents\NetBeansProjects\ScrapeTestForStackDe\Urls\" + title + ".csv");
File f = new File(GimmeAName);
FileWriter fw = new FileWriter(f);
PrintWriter out = new PrintWriter(fw);
StuffToWrite = URLArray[counter];
// fetch the document over HTTP
Elements spangrabbers = doc.getElementsByClass("art_orginal_preis142790");
for (Element spangrab : spangrabbers)
{
//System.out.println("New Span: ");
//System.out.println(spangrab);
holder2 = spangrab.text();
//System.out.println(holder2);
SpanHolderArray[SpanHolderCounter] = holder2;
SpanHolderCounter++;
}
// get all links in page
Elements links = doc.select("a[href]");
for (Element link : links) {
// get the value from the href attribute
checker = link.attr("href");
if (checker.contains("http"))
{
}
else if(checker.contains("javascript"))
{
}
else if(checker.contains("style"))
{
}
else
{
counter++;
if(LinkContorter == null && LinkContorter.isEmpty())
{
//do nothing
}
else
{
System.out.println(LinkContorter);
out.print(LinkContorter);
out.print(",");
out.print("\n");
//Flush the output to the file
out.flush();
}
}
}
System.out.println(counter);
//Close the Print Writer
out.close();
//Close the File Writer
fw.close();
有没有可能你们中的一些人可以尝试抓取这个网站,看看你们是否得到了和我一样的结果?我怀疑可能有一些防止抓取的安全措施,但是,我不想放弃这个任务,除非我知道情况确实如此。几个月前的二月或三月,我也曾经毫无问题地抓取过同一个网站。
如果您不发送任何敏感数据,您可以稍微作弊并配置您自己的 TrustManger 以接受所有内容。
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
}
} };
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
现在它将用于每个连接,因此不推荐使用。相反,您可以注释掉最后一行,并通过指定 SSLSocketFactory 使 jsoup 仅将其用于单个连接:
// HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); // not needed anymore
Document doc = Jsoup.connect(URL)
.sslSocketFactory(sc.getSocketFactory())
.get();
虽然 Firefox 显示此服务器使用的证书确实使用中间 CA Sectigo RSA Domain Validation Secure Server CA
和根 CA USERTrust RSA Certification Authority
进行验证,但服务器仅发送叶证书而不发送中间证书 'chain' 标准要求的证书。
您可以通过查看 SSLLabs test report; notice the orange warning in the summary openssl s_client -connect www.strack.de:443 -showcerts
(如今许多服务器需要 SNI,对于低于 1.1.1 的 OpenSSL 发送 SNI,您需要添加 -servername $host
而不是 this 服务器),或者因为你有 Java keytool -printcert -sslserver www.strack.de
.
省略所需的链证书是懒得阅读文档的服务器管理员的一个常见错误,因为如果他们只使用一两个浏览器进行测试,他们不会注意到这个错误——浏览器通常可以解决缺少的链证书,但大多数其他软件,包括 Java,默认情况下不能或不能。它不太可能被用作故意的反抓取措施,因为它很容易被绕过,请参阅下一页,但它确实表明服务器管理员没有实际目标或兴趣 支持或协助抓取。
而不是忽略 所有 证书问题,因为 http://crt.sectigo.com/SectigoRSADomainValidationSecureServerCA.crt
中的 caIssuer link(在 SSLLabs 报告或 keytool -printcert
解码中显示,或者如果您 运行 openssl s_client
输出到 openssl x509 -noout -text
) -- 并将其添加到您的信任库(默认情况下文件 $JREDIR/lib/security/cacerts
或 jssecacerts
除非您使用 sysprop 或代码更改它)。
(已添加)Re Firefox,您已经发现 UI 在您 link 编辑的 Q 之后的几年中发生了细微变化:您现在单击挂锁,然后单击右箭头、更多信息、查看证书。要导出特定证书,请单击“Sectigo RSA ...”选项卡并向下滚动到一半:
您也可以将此问题报告给站点管理员或所有者。他们是否会关心你或一般的非浏览器访问我不知道。