Ottengo un'eccezione SocketTimeoutException in Jsoup: lettura scaduta


100


Ottengo un'eccezione SocketTimeoutException quando provo ad analizzare molti documenti HTML utilizzando Jsoup.
Ad esempio, ho un elenco di link:

<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>

Per ogni collegamento, analizzo il documento collegato all'URL (dall'attributo href) per ottenere altre informazioni in quelle pagine.
Quindi posso immaginare che ci voglia molto tempo, ma come disattivare questa eccezione?
Ecco l'intera traccia dello stack:

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)

Grazie amici!

EDIT: Hum ... Scusa, ho appena trovato la soluzione:

Jsoup.connect(url).timeout(0).get();

Spero che possa essere utile per qualcun altro ... :)


3
Il codice aggiunto nella modifica imposta il timeout su infinito. Ciò è indesiderabile nella maggior parte dei casi d'uso. È molto meglio utilizzare un timeout specifico come indicato nella risposta MarcoS, anche se il timeout è lungo.
Stepanian

2
Immagino timeout(0)che Jsoup collegherà l'URL ancora e ancora finché non si connetterà.
Evan Hu

Risposte:


138

Penso che tu possa fare

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

che imposta il timeout a 10s.


3
121 voti positivi ma nessuna spiegazione del motivo per cui questo risolve il problema? Perché questo risolve il problema quando l'impostazione predefinita è 30 secondi?
Alan Hay

2
@AlanHay la mia risposta stava suggerendo di risolvere il problema impostando un timeout, non utilizzando quel valore specifico come timeout :)
MarcoS

26

Ok, quindi, ho provato a offrire questo come modifica alla risposta di MarcoS, ma la modifica è stata rifiutata. Tuttavia, le seguenti informazioni potrebbero essere utili ai futuri visitatori:

Secondo i javadoc , il timeout predefinito per un org.jsoup.Connectionè di 30 secondi.

Come è già stato accennato, questo può essere impostato utilizzando timeout(int millis)

Inoltre, come osserva l'OP nella modifica, questo può essere impostato anche utilizzando timeout(0). Tuttavia, come affermano i javadoc:

Un timeout pari a zero viene considerato come un timeout infinito.


3
L'impostazione di un timeout infinito è una cattiva idea nella maggior parte dei casi. Usa un timeout lungo, ma specificane sempre uno. Vedi la risposta di MarcoS.
Stepanian

3
@stepanian - per essere chiari, non sto sostenendo l'impostazione di un timeout infinito. Questa era stata suggerita come soluzione dall'OP, sebbene volessi indirizzare i futuri utenti alle implicazioni di ciò. Infatti, quando ho inizialmente pubblicato la mia "risposta", ho indicato che pensavo che avrebbe dovuto essere una modifica alla risposta di MacroS, poiché c'erano alcune informazioni aggiuntive che potrebbero essere utili per i futuri utenti ... ma la modifica è stata rifiutata.
amaidment

Il timeout predefinito non è di 3 secondi, ma di 30 secondi (30000 millisecondi), puoi vederlo in jsoup.org/apidocs/org/jsoup/Connection.html
aldok


3

Ho avuto lo stesso errore:

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)

e solo l'impostazione ha .userAgent(Opera)funzionato per me.

Quindi ho usato il Connection userAgent(String userAgent)metodo della classe Connection per impostare l'agente utente Jsoup.

Qualcosa di simile a:

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


-6

Imposta il timeout durante la connessione da jsoup.


2
Si prega di aggiungere ulteriori informazioni sulla risposta
Joe Taras,

Supporta la tua risposta con spiegazioni e snippet di codice, se necessario.
Swapnil B.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.