Jsoup은 HTML을 파싱하고 조작하며 데이터를 추출하는 Java 라이브러리입니다. jQuery나 CSS 선택자를 사용하여 요소를 선택할 수 있습니다.

의존성 추가

compile 'org.jsoup:jsoup:1.11.2'

Input (문서 가져오기)

문자열에서 파싱

String html = "<html><head><title>First parse</title></head>"
  + "<body><p>Parsed HTML into a doc.</p></body></html>";
Document doc = Jsoup.parse(html);

baseUri를 지정하면 상대 URL을 절대 URL로 변환할 수 있습니다:

Jsoup.parse(String html, String baseUri)

GET 요청

Document doc = Jsoup.connect("http://en.wikipedia.org/").get();

POST 요청

Document doc = Jsoup.connect("http://example.com")
  .data("query", "Java")
  .userAgent("Mozilla")
  .cookie("auth", "token")
  .timeout(3000)
  .post();

JSON 응답 받기

String json = Jsoup.connect("https://api.example.com/data")
        .ignoreContentType(true)
        .execute()
        .body();

Output (데이터 추출)

DOM 메서드

Element content = doc.getElementById("content");
Elements links = content.getElementsByTag("a");
for (Element link : links) {
  String linkHref = link.attr("href");
  String linkText = link.text();
}

Selector 문법 (jQuery/CSS 선택자)

File input = new File("/tmp/input.html");
Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/");

Elements links = doc.select("a[href]"); // href 속성이 있는 a 태그
Elements pngs = doc.select("img[src$=.png]"); // src가 .png로 끝나는 img
Element masthead = doc.select("div.masthead").first(); // class=masthead인 div
Elements resultLinks = doc.select("h3.r > a"); // h3 바로 다음의 a 태그
Elements newsHeadlines = doc.select("#mp-itn b a");

데이터 추출

String html = "<p>An <a href='http://example.com/'><b>example</b></a> link.</p>";
Document doc = Jsoup.parse(html);
Element link = doc.select("a").first();

String text = doc.body().text(); // "An example link"
String linkHref = link.attr("href"); // "http://example.com/"
String linkText = link.text(); // "example"
String linkOuterH = link.outerHtml(); // "<a href="http://example.com"><b>example</b></a>"
String linkInnerH = link.html(); // "<b>example</b>"

절대 URL 얻기

Document doc = Jsoup.connect("http://jsoup.org").get();
Element link = doc.select("a").first();

String relHref = link.attr("href"); // "/"
String absHref = link.attr("abs:href"); // "http://jsoup.org/"

// 또는
headline.absUrl("href")

Modify (문서 수정)

속성 일괄 수정

doc.select("div.comments a").attr("rel", "nofollow");

HTML 수정

Element div = doc.select("div").first(); // <div></div>
div.html("<p>lorem ipsum</p>"); // <div><p>lorem ipsum</p></div>
div.prepend("<p>First</p>");
div.append("<p>Last</p>");
// 결과: <div><p>First</p><p>lorem ipsum</p><p>Last</p></div>

Element span = doc.select("span").first(); // <span>One</span>
span.wrap("<li><a href='http://example.com/'></a></li>");
// 결과: <li><a href="http://example.com"><span>One</span></a></li>

텍스트 수정

div.text("five > four"); // <div>five &gt; four</div>
div.prepend("First ");
div.append(" Last");
// 결과: <div>First five &gt; four Last</div>

에러 처리

403 에러 해결

User-Agent를 Mozilla로 설정합니다:

return Jsoup.connect("http://example.com/search?query=test")
        .userAgent("Mozilla")
        .get()
        .select(".result")
        .first()
        .text();

XSS 공격 방지

사용자 입력에서 스크립트를 제거하여 XSS 공격을 방지합니다.

String unsafe =
  "<p><a href='http://example.com/' onclick='stealCookies()'>Link</a></p>";
String safe = Jsoup.clean(unsafe, Whitelist.basic());
// 결과: <p><a href="http://example.com/" rel="nofollow">Link</a></p>

Feedback 입력, 질문 입력, ID/PW 입력 등 모든 입력 창은 잠재적으로 스크립트 공격 가능성이 있습니다. 사용자가 feedback에 스크립트를 작성하면, CMS에서 해당 feedback을 확인할 때 스크립트가 실행되어 정보가 노출될 수 있습니다.