Jsoup SocketTimeoutException:读取超时

Posted

技术标签:

【中文标题】Jsoup SocketTimeoutException:读取超时【英文标题】:Jsoup SocketTimeoutException: Read timed out 【发布时间】:2011-09-28 03:08:23 【问题描述】:

当我尝试使用 Jsoup 解析大量 html 文档时,我得到一个 SocketTimeoutException

例如,我得到了一个链接列表:

<a href="www.domain.com/url1.html">link1</a>
<a href="www.domain.com/url2.html">link2</a>
<a href="www.domain.com/url3.html">link3</a>
<a href="www.domain.com/url4.html">link4</a>

对于每个链接,我都会解析链接到 URL 的文档(来自 href 属性)以获取这些页面中的其他信息。

所以我可以想象它需要很多时间,但是如何关闭这个异常这里是整个堆栈跟踪:

java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(Unknown Source)
    at java.io.BufferedInputStream.fill(Unknown Source)
    at java.io.BufferedInputStream.read1(Unknown Source)
    at java.io.BufferedInputStream.read(Unknown Source)
    at sun.net.www.http.HttpClient.parseHTTPHeader(Unknown Source)
    at sun.net.www.http.HttpClient.parseHTTP(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
    at java.net.HttpURLConnection.getResponseCode(Unknown Source)
    at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:381)
    at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:364)
    at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:143)
    at org.jsoup.helper.HttpConnection.get(HttpConnection.java:132)
    at app.ForumCrawler.crawl(ForumCrawler.java:50)
    at Main.main(Main.java:15)

【问题讨论】:

您在编辑中添加的代码将超时设置为无限。这在大多数用例中是不可取的。最好使用 MarcoS 答案中指示的特定超时,即使超时很长。 我猜timeout(0)会让Jsoup一次又一次地连接url直到它连接。 这似乎是问题作者C. MaillardJsoup.connect(url).timeout(0).get();根据earlier revision找到的解决方案 【参考方案1】:

这应该有效: Jsoup.connect(url.toLowerCase()).timeout(0);.

【讨论】:

【参考方案2】:

我有同样的错误:

java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:171)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)

只有设置 .userAgent(Opera) 对我有用。

所以我使用Connection类的Connection userAgent(String userAgent)方法来设置Jsoup用户代理。

类似:

Jsoup.connect("link").userAgent("Opera").get();

【讨论】:

【参考方案3】:

我觉得你可以的

Jsoup.connect("...").timeout(10 * 1000).get(); 

将超时设置为 10 秒。

【讨论】:

121 次赞成但没有解释为什么这可以解决问题?当默认值显示为 30 秒时,为什么这能解决问题? @AlanHay 我的回答是建议通过设置超时来解决问题,而不是使用该特定值作为超时:) @AlanHay,写问答时的默认超时时间是 3 秒。因此,任何增加都会降低套接字超时频率并有助于解决问题。我在 2016 年将默认值更新为 30 秒。【参考方案4】:

https://jsoup.org/apidocs/org/jsoup/Connection.html 有错误。 默认超时不是 30 秒。这是 3 秒。 只需查看代码中的 javadoc。它说 3000 毫秒。

【讨论】:

在 java doc 上:“默认超时为 30 秒(30,000 毫秒)。零超时被视为无限超时。” jsoup.org/apidocs/org/jsoup/Connection.html【参考方案5】:

好的 - 所以,我尝试将此作为对 MarcoS 答案的编辑,但该编辑被拒绝。不过,以下信息可能对未来的访问者有用:

根据javadocs,org.jsoup.Connection 的默认timeout 为 30 秒。

正如已经提到的,这可以使用timeout(int millis)进行设置

此外,正如编辑中的 OP 注释,这也可以使用 timeout(0) 进行设置。但是,正如 javadocs 所述:

零超时被视为无限超时。

【讨论】:

在大多数情况下设置无限超时是一个坏主意。使用长超时,但始终指定一个。请参阅 MarcoS 的答案。 @stepanian - 明确地说,我不提倡设置无限超时。这已被 OP 建议为解决方案,尽管我想引导未来的用户了解这一点。事实上,当我最初发布我的“答案”时,我表示我认为它应该是对 MacroS 答案的编辑,因为有一些额外的信息可能对未来的用户有用......但编辑被拒绝了。跨度> 默认超时不是3秒,而是30秒(30000毫秒),可以在jsoup.org/apidocs/org/jsoup/Connection.html看到 过去的超时时间是 3 秒,回到写问题的时候。【参考方案6】:

从 jsoup 连接时设置超时。

【讨论】:

请添加有关您的答案的更多信息 如有必要,请用解释和代码 sn-ps 支持您的回答。

以上是关于Jsoup SocketTimeoutException:读取超时的主要内容,如果未能解决你的问题,请参考以下文章

JSOUP教程,JSOUP 乱码处理,JSOUP生僻字乱码解决方案

Jsoup错误java.lang.NoClassDefFoundError: org.jsoup.Jsoup

Jsoup的demao

Jsoup爬虫最终修订版

jsoup教程

Java 实现 HttpClients+jsoup,Jsoup,htmlunit,Headless Chrome 爬虫抓取数据