J'obtiens une SocketTimeoutException dans Jsoup: la lecture a expiré


100


J'obtiens une SocketTimeoutException lorsque j'essaye d'analyser beaucoup de documents HTML en utilisant Jsoup.
Par exemple, j'ai une liste de liens:

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

Pour chaque lien, j'analyse le document lié à l'URL (à partir de l'attribut href) pour obtenir d'autres informations dans ces pages.
Je peux donc imaginer que cela prend beaucoup de temps, mais comment fermer cette exception?
Voici toute la trace de la pile:

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)

Merci les copains!

EDIT: Hum ... Désolé, vient de trouver la solution:

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

J'espère que cela pourrait être utile pour quelqu'un d'autre ... :)


3
Le code que vous avez ajouté dans votre modification définit le délai d'expiration à l'infini. Ceci n'est pas souhaitable dans la plupart des cas d'utilisation. Il est préférable d'utiliser un délai d'expiration spécifique comme indiqué dans la réponse MarcoS, même si le délai d'attente est long.
stepanian

2
Je suppose timeout(0)que Jsoup reliera l'URL encore et encore jusqu'à ce qu'il se connecte.
Evan Hu

Réponses:


138

Je pense que tu peux faire

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

qui définit le délai d'expiration à 10 s.


3
121 votes positifs mais aucune explication de la raison pour laquelle cela résout le problème? Pourquoi cela résout le problème alors que la valeur par défaut est, semble-t-il, 30 secondes?
Alan Hay

2
@AlanHay ma réponse suggérait de résoudre le problème en définissant un délai, et non en utilisant cette valeur spécifique comme délai d'expiration :)
MarcoS

26

Ok - donc, j'ai essayé de proposer ceci comme une modification à la réponse de MarcoS, mais la modification a été rejetée. Néanmoins, les informations suivantes peuvent être utiles aux futurs visiteurs:

Selon les javadocs , le délai d' expiration par défaut pour an org.jsoup.Connectionest de 30 secondes.

Comme cela a déjà été mentionné, cela peut être défini en utilisant timeout(int millis)

En outre, comme le note OP dans l'édition, cela peut également être défini à l'aide de timeout(0). Cependant, comme l'état javadocs:

Un timeout de zéro est traité comme un timeout infini.


3
Définir un délai d'expiration infini est une mauvaise idée dans la plupart des cas. Utilisez un long délai, mais spécifiez-en toujours un. Voir la réponse de MarcoS.
stepanian

3
@stepanian - pour être clair, je ne préconise pas de définir un délai d'attente infini. Cela avait été suggéré comme solution par le PO, même si je voulais orienter les futurs utilisateurs vers les implications de cela. En effet, lorsque j'ai initialement publié ma 'réponse', j'ai indiqué que je pensais que cela aurait dû être une modification de la réponse de MacroS, car il y avait des informations supplémentaires qui pourraient être utiles aux futurs utilisateurs ... mais la modification a été rejetée.
indemnité le

Le délai d'expiration par défaut n'est pas de 3 secondes, mais de 30 secondes (30000 millis), vous pouvez le voir dans jsoup.org/apidocs/org/jsoup/Connection.html
aldok


3

J'ai eu la même erreur:

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)

et seul le réglage a .userAgent(Opera)fonctionné pour moi.

J'ai donc utilisé la Connection userAgent(String userAgent)méthode de la classe Connection pour définir l'agent utilisateur Jsoup.

Quelque chose comme:

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


-6

Définissez le délai d'expiration lors de la connexion depuis jsoup.


2
S'il vous plaît ajouter plus d'informations sur votre réponse
Joe Taras

Veuillez soutenir votre réponse avec des explications et des extraits de code si nécessaire.
Swapnil B.
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.