0. 아이스브레이크를 위한 서론
-
예전에 Jsoup을 사용해서 크롤링 예제를 만든적이 있습니다만, Jsoup에 대한 이해도가 낮아 Apache HTTP를 사용해서 만든적이 있습니다.
-
결론부터 말하면, Jsoup 자체가 HTTP Connection 을 기반으로 만들어졌기 때문에 단독 라이브러리로도 웹 크롤링이 충분히 가능 합니다.
-
짧게 말해서 그냥 Jsoup Jar 하나면 웹 크롤링이 가능합니다.
-
Java Project는 1.7 / 1.8 에 대해서는 테스트 해보았습니다.
-
빠르게 실무 적용이 가능한 예제를 보시려면 제일 아래로 내리세요.
1. Jsoup 다운로드 및 프로젝트 추가
-
다운로드
-
File
-
jsoup-1.11.2.jar core library
-
jsoup-1.11.2-sources.jar optional sources jar
-
jsoup-1.11.2-javadoc.jar optional javadoc jar
-
-
다운로드 파일은?
-
기본적으로 jsoup-x.xx.x.jar 만 다운 받아도 됩니다만 source로 들여다 보고 싶다, API도 보고 싶다하면 선택적으로 -sources나 -javadoc jar 도 다운로드 받으시면 됩니다.
-
-
프로젝트 추가
-
여기서 설명하는 예제는 기본 Java Project로 만들었고 수동 Build Path를 통해 Jar를 등록했습니다.
-
Maven 에서는 아래와 같이 사용하시면 됩니다.
<dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.11.2</version> </dependency>
-
2. 가장 기본이 되는 Jsoup GET 방식 예제
-
가장 기본이 되는 GET 방식 예제는 아래와 같습니다.
try { // 1. URL 선언 String connUrl = "https://www.daum.net"; // 2. HTML 가져오기 Document doc = Jsoup.connect(connUrl).get(); // 3. 가져온 HTML Document 를 확인하기 System.out.println(doc.toString()); } catch (IOException e) { // Exp : Connection Fail e.printStackTrace(); }
3. 가장 기본이 되는 Jsoup POST 방식 예제
-
가장 기본이 되는 Jsoup POST 방식 호출은 아래와 같습니다.
try { // 1. URL 선언 String connUrl = "http://map.daum.net"; // 2. HTML 가져오기 Document doc = Jsoup.connect(connUrl).post(); // TODO POST의 data 값은 Jsoup.data(...) 을 사용하시면 됩니다. // 3. 가져온 HTML Document 를 확인하기 System.out.println(doc.toString()); } catch (IOException e) { // Exp : Connection Fail e.printStackTrace(); }
-
POST의 data 값은 Jsoup.data(...) 을 사용하시면 됩니다.
-
4. 쓸만한 Jsoup 예제
-
기본 예제는 Hello World 예제를 보셨다면, 실제로 적용하기에는 문제들이 있습니다.
-
USER AGENT 가 없어 Malform URL 이 될 수 있습니다.
-
HTTPS 호출 시, 인증서가 없어 에러가 발생합니다.
-
-
위에 두가지에 대해서 적용가능한 JSOUP 예제는 계속해서 예제로 설명드리겠습니다.
이슈해결 > Malform URL 은 어떻게?
-
Malform URL 에러는 아래와 같이 header / userAgent / ignoreContentType(true) 옵션을 추가하면 해결 됩니다.
private final static String USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36";
public static void main(String[] args) {
try {
// 1. URL 선언
String connUrl = "http://map.daum.net";
// 2. HTML 가져오기
Connection conn = Jsoup.connect(connUrl)
.header("Content-Type", "application/json;charset=UTF-8")
.userAgent(USER_AGENT)
.method(Connection.Method.GET)
.ignoreContentType(true);
Document doc = conn.get();
// 3. 가져온 HTML Document 를 확인하기
System.out.println(doc.toString());
} catch (IOException e) {
// Exp : Connection Fail
e.printStackTrace();
}
}
이슈해결 > SSL (HTTPS) 은 어떻게 호출해야하나?
-
아래 에러는 SSL 인증 에러입니다.
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979) at sun.security.ssl.Handshaker.process_record(Handshaker.java:914) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387) at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185) at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153) at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:730) at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:706) at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:299) at org.jsoup.helper.HttpConnection.get(HttpConnection.java:288) at com.derveljun.jsoup.JsoupCrawlerExample.main(JsoupCrawlerExample.java:27)Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387) at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292) at sun.security.validator.Validator.validate(Validator.java:260) at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324) at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229) at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1491) ... 15 moreCaused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141) at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126) at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280) at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382) ... 21 more
-
SSL 에러 발생은 아래 예제를 통해 적용가능합니다. JAVA Vers해봅니다. SSL을 우회적으로 인증하는 방법입니다.
// SSL 우회 등록 public static void setSSL() throws NoSuchAlgorithmException, KeyManagementException { TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) {} public void checkServerTrusted(X509Certificate[] certs, String authType) {} } }; SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new SecureRandom()); HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); }
-
SSL 설정을 메소드로 따로 빼서 사용하는 예제 입니다.
package com.derveljun.jsoup; import java.io.IOException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.cert.X509Certificate; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import org.jsoup.Connection; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; public class JsoupCrawlerExample { private final static String USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36"; // SSL 우회 등록 public static void setSSL() throws NoSuchAlgorithmException, KeyManagementException { TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) {} public void checkServerTrusted(X509Certificate[] certs, String authType) {} } }; SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new SecureRandom()); HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } public static void main(String[] args) { try { // 1. URL 선언 String connUrl = "https://www.daum.net"; // 2. SSL 체크 if (connUrl.indexOf("https://") >= 0) { JsoupCrawlerExample.setSSL(); } // 3. HTML 가져오기 Connection conn = Jsoup.connect(connUrl).header("Content-Type", "application/json;charset=UTF-8").userAgent(USER_AGENT).method(Connection.Method.GET).ignoreContentType(true); Document doc = conn.get(); // 4. 가져온 HTML Document 를 확인하기 System.out.println(doc.toString()); } catch (IOException e) { // Exp : Connection Fail e.printStackTrace(); } catch (KeyManagementException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
-
점심시간 안에 끝내려고 했는데 시간이 너무 많이 지났네요 ^^;;
다음에 시간되면 조금더 글좀 다듬겠습니다.
부족한 부분이나 첨언 / 문의 사항은 댓글 부탁드립니다.
'Java & Spring > 도움이 되는' 카테고리의 다른 글
마크다운 Markdown 렌더링Rendering / 컨버터Converter 라이브러리 추천 (0) | 2019.02.14 |
---|---|
네티 관련 좋은 git URL (0) | 2018.04.11 |
Properties 사용 예제 (0) | 2014.01.02 |
Eclipse 에서 UML 그리기 : AmaterasUML (0) | 2013.10.17 |
Eclipse에 Spring 설치 및 Maven 연동 (0) | 2013.10.17 |
WRITTEN BY