Ich erhalte eine SocketTimeoutException in Jsoup: Zeitüberschreitung beim Lesen

100


Ich erhalte eine SocketTimeoutException, wenn ich versuche, viele HTML-Dokumente mit Jsoup zu analysieren.
Zum Beispiel habe ich eine Liste von Links:

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

Für jeden Link analysiere ich das mit der URL verknüpfte Dokument (aus dem href-Attribut), um andere Informationen auf diesen Seiten zu erhalten.
Ich kann mir also vorstellen, dass es viel Zeit kostet, aber wie kann man diese Ausnahme ausschalten?
Hier ist die gesamte Stapelverfolgung:

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)

Danke Kumpels!

EDIT: Hum ... Sorry, habe gerade die Lösung gefunden:

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

Hoffe das könnte für jemand anderen nützlich sein ... :)

C. Maillard
quelle
3
Der Code, den Sie in Ihrer Bearbeitung hinzugefügt haben, setzt das Zeitlimit auf unendlich. Dies ist in den meisten Anwendungsfällen unerwünscht. Es ist viel besser, ein bestimmtes Zeitlimit zu verwenden, wie in der MarcoS-Antwort angegeben, auch wenn das Zeitlimit lang ist.
Stepanian
2
Ich denke, das timeout(0)wird Jsoup dazu bringen, die URL immer wieder zu verbinden, bis sie sich verbindet.
Evan Hu

Antworten:

138

Ich denke du kannst es tun

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

Dadurch wird das Zeitlimit auf 10 Sekunden gesetzt.

MarcoS
quelle
3
121 positive Stimmen, aber keine Erklärung, warum dies das Problem behebt? Warum wird das Problem dadurch behoben, wenn die Standardeinstellung 30 Sekunden beträgt?
Alan Hay
2
@AlanHay Meine Antwort war, das Problem durch Festlegen eines Zeitlimits zu lösen, nicht durch Verwenden dieses bestimmten Werts als Zeitlimit :)
MarcoS
26

Ok - also habe ich versucht, dies als Bearbeitung für die Antwort von MarcoS anzubieten, aber die Bearbeitung wurde abgelehnt. Die folgenden Informationen können jedoch für zukünftige Besucher nützlich sein:

Laut den Javadocs ist das Standard- Timeout für einorg.jsoup.Connection 30 Sekunden.

Wie bereits erwähnt, kann dies mit eingestellt werden timeout(int millis)

Wie die OP-Hinweise in der Bearbeitung zeigen, kann dies auch mit eingestellt werden timeout(0). Wie die Javadocs jedoch sagen:

Eine Zeitüberschreitung von Null wird als unendliche Zeitüberschreitung behandelt.

Amaidment
quelle
3
Das Festlegen einer unendlichen Zeitüberschreitung ist in den meisten Fällen eine schlechte Idee. Verwenden Sie eine lange Zeitüberschreitung, geben Sie jedoch immer eine an. Siehe MarcoS Antwort.
Stepanian
3
@stepanian - um klar zu sein, ich befürworte nicht, eine unendliche Zeitüberschreitung festzulegen. Dies wurde vom OP als Lösung vorgeschlagen, obwohl ich zukünftige Benutzer auf die Auswirkungen davon hinweisen wollte. Als ich meine "Antwort" ursprünglich veröffentlichte, gab ich an, dass ich dachte, es hätte eine Bearbeitung der Antwort von MacroS sein sollen, da es einige zusätzliche Informationen gab, die für zukünftige Benutzer nützlich sein könnten ... aber die Bearbeitung wurde abgelehnt.
Amaidment
Das Standardzeitlimit beträgt nicht 3 Sekunden, sondern 30 Sekunden (30000 Millis). Sie können es unter jsoup.org/apidocs/org/jsoup/Connection.html
aldok
3

Ich hatte den gleichen Fehler:

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)

und nur Einstellung .userAgent(Opera) hat bei mir funktioniert.

Also habe ich benutzt Connection userAgent(String userAgent) Methode der Verbindungsklasse verwendet, um den Jsoup-Benutzeragenten festzulegen.

Etwas wie:

Jsoup.connect("link").userAgent("Opera").get();
invzbl3
quelle
-1

Dies sollte funktionieren : Jsoup.connect(url.toLowerCase()).timeout(0);.

Prasanna Mendon
quelle
-6

Stellen Sie das Zeitlimit ein, während Sie eine Verbindung von jsoup herstellen.

Gaurab Pradhan
quelle
2
Bitte fügen Sie weitere Informationen zu Ihrer Antwort hinzu
Joe Taras
Bitte unterstützen Sie Ihre Antwort bei Bedarf mit Erklärungen und Codefragmenten.
Swapnil B.