Jsoup SocketTimeoutException: อ่านหมดเวลา


101

ฉันได้รับSocketTimeoutExceptionเมื่อพยายามแยกวิเคราะห์เอกสาร HTML จำนวนมากโดยใช้ Jsoup

ตัวอย่างเช่นฉันได้รับรายการลิงก์:

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

3
รหัสที่คุณเพิ่มในการแก้ไขตั้งค่าระยะหมดเวลาเป็นอนันต์ นี่เป็นสิ่งที่ไม่พึงปรารถนาในกรณีการใช้งานส่วนใหญ่ จะดีกว่ามากหากใช้การหมดเวลาเฉพาะตามที่ระบุไว้ในคำตอบของ MarcoS แม้ว่าระยะหมดเวลาจะนาน
stepanian

2
ฉันเดาว่าtimeout(0)จะทำให้ Jsoup เชื่อมต่อ url ซ้ำแล้วซ้ำอีกจนกว่าจะเชื่อมต่อ
Evan Hu

คำตอบ:


138

ฉันคิดว่าคุณสามารถทำได้

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

ซึ่งตั้งค่าการหมดเวลาเป็น 10 วินาที


3
121 upvotes แต่ไม่มีคำอธิบายว่าเหตุใดจึงแก้ไขปัญหาได้? เหตุใดจึงแก้ไขปัญหาเมื่อค่าเริ่มต้นคือจะปรากฏขึ้น 30 วินาที
Alan Hay

2
@Alan คำตอบของฉันคือแนะนำให้แก้ปัญหาโดยการตั้งค่าการหมดเวลาไม่ใช่โดยใช้ค่าเฉพาะนั้นเป็นระยะหมดเวลา :)
MarcoS

26

ตกลง - ฉันพยายามเสนอสิ่งนี้เป็นการแก้ไขคำตอบของ MarcoS แต่การแก้ไขถูกปฏิเสธ อย่างไรก็ตามข้อมูลต่อไปนี้อาจเป็นประโยชน์สำหรับผู้เยี่ยมชมในอนาคต:

ตามที่javadocsค่าเริ่มต้นหมดเวลาสำหรับorg.jsoup.Connectionคือ 30 วินาที

ดังที่ได้กล่าวไปแล้วสามารถตั้งค่าโดยใช้ timeout(int millis)

นอกจากนี้ในฐานะที่เป็นบันทึก OP ในการแก้ไขก็สามารถตั้งค่าโดยใช้timeout(0)ไฟล์. อย่างไรก็ตามในขณะที่ javadocs ระบุ:

การหมดเวลาเป็นศูนย์จะถือว่าเป็นการหมดเวลาที่ไม่มีที่สิ้นสุด


3
การกำหนดระยะหมดเวลาที่ไม่สิ้นสุดเป็นความคิดที่ไม่ดีในกรณีส่วนใหญ่ ใช้การหมดเวลานาน แต่ระบุอย่างใดอย่างหนึ่งเสมอ ดูคำตอบของ MarcoS
stepanian

3
@stepanian - เพื่อความชัดเจนฉันไม่สนับสนุนการตั้งค่าการหมดเวลาที่ไม่สิ้นสุด สิ่งนี้ได้รับการแนะนำให้เป็นโซลูชันโดย OP แม้ว่าฉันต้องการนำผู้ใช้ในอนาคตไปสู่ผลกระทบของสิ่งนี้ อันที่จริงเมื่อฉันโพสต์ 'คำตอบ' ในตอนแรกฉันระบุว่าฉันคิดว่าควรจะแก้ไขคำตอบของ MacroS เนื่องจากมีข้อมูลเพิ่มเติมบางอย่างที่อาจเป็นประโยชน์กับผู้ใช้ในอนาคต ... แต่การแก้ไขถูกปฏิเสธ
แก้ไข

ระยะหมดเวลาเริ่มต้นไม่ใช่ 3 วินาที แต่เป็น 30 วินาที (30000 มิลลิ
aldok

3

มีความผิดพลาดอยู่บนhttps://jsoup.org/apidocs/org/jsoup/Connection.html ระยะหมดเวลาเริ่มต้นไม่ใช่ 30 วินาที 3 วินาที เพียงแค่ดู javadoc ในรหัส มันบอกว่า 3000 ms


1
ใน java doc: "การหมดเวลาเริ่มต้นคือ 30 วินาที (30,000 มิลลิวินาที) การหมดเวลาเป็นศูนย์จะถือว่าเป็นการหมดเวลาที่ไม่มีที่สิ้นสุด" jsoup.org/apidocs/org/jsoup/Connection.html
jeton

3

ฉันมีข้อผิดพลาดเดียวกัน:

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 userAgent(String userAgent)วิธีการของคลาสการเชื่อมต่อเพื่อตั้งค่าตัวแทนผู้ใช้ Jsoup

สิ่งที่ต้องการ:

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


-6

ตั้งค่าหมดเวลาขณะเชื่อมต่อจาก jsoup


2
โปรดเพิ่มข้อมูลเพิ่มเติมเกี่ยวกับคำตอบของคุณ
Joe Taras

โปรดสนับสนุนคำตอบของคุณพร้อมคำอธิบายและตัวอย่างโค้ดหากจำเป็น
Swapnil B.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.