
1) Document 클래스
getElementById 만 Element 이고, 나머지는 Elements 라는 점입니다. Id는 하나의 Element만 가지고 있는 고유 속성이기 때문에 단일 Element를 돌려줍니다. 그리고 Elements는 ArrayList*<Element*> 같은 것이 아니고 Elements라고 하는 객체가 따로 존재합니다. 그래도 Elements는 List 인터페이스를 구현했기 때문에 일반 리스트 처럼 사용할 수 있습니다.
Element 객체가 할 수 있는 작업
select
doc.select("a") : <a> 요소를 모두 선택
doc.select("#logo") : id="logo" 인 요소를 선택
doc.select(".list") : class="list"인 요소들을 선택
https://jsoup.org/download
https://mvnrepository.com/artifact/org.jsoup/jsoup

https://www.hanbit.co.kr/store/books/new_book_list.html
이 홈페이지에서 도서명과 이미지 가져오기
1. vo 만들기
String title 제목
String link 이미지 링크
// @GetMapping("/newbook")
// public HashMap<String, String> newBook(Model model) {
// HashMap<String, String> map = new HashMap<String, String>();
// String base = "https://www.hanbit.co.kr";
// String url = "https://www.hanbit.co.kr/store/books/new_book_list.html";
// try {
// // jsoup을 통해서 doc객체 생성
// Document doc = Jsoup.connect(url).get();
// // 찾고자 하는 Elements를 찾아서 검색
// // 배열을 반환
// Elements list = doc.select(".book_tit");
//
// for (Element e: list) {
// // 첫번째 자식 Element를 반환
// Element a = e.firstElementChild();
// // attr로 속성 접근
// String link = base + a.attr("href");
// String text = a.text();
//
// map.put(text, link);
// }
// } catch (Exception e) {
// System.out.println(e.getMessage());
// }
//
// model.addAttribute("map", map);
// return map;
// }
connect 메소드로 크롤링할 URL을 연결하고get 메소드로 document를 가져온다. 긁어온 document에서 select 메소드를 사용해서 element를 찾으면 된다.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>도서목록</h2>
<hr>
<ul>
<li th:each="m:${map}">
<a th:href="${m.value}" th:text="${m.key}"></a>
</li>
</ul>
</body>
</html>
@GetMapping("/newbook")
public List<NewBook> newBook(Model model) {
List<NewBook> bookList = new ArrayList<NewBook>();
// 이 홈페이지의 최대 페이지 수는 86페이지
int i = 1;
try {
// String url2 = "https://www.hanbit.co.kr/store/books/new_book_list.html?page=86";
// 페이지 넘어서 조회시 오류 확인
// Connection conn = Jsoup.connect(url2);
// System.out.println(conn);
// Document doc2 = Jsoup.connect(url2).get();
// Elements list2 = doc2.select(".book_tit");
// list2의 null값을 확인하려 했지만 값이 들어가 있음
// size를 통해 확인
// if (list2.size() == 0) {
// System.out.println("86페이지 없음");
// }
while (true) {
String url = "https://www.hanbit.co.kr/store/books/new_book_list.html?page=" + i;
// jsoup을 통해서 doc객체 생성
Document doc = Jsoup.connect(url).get();
// 찾고자 하는 Elements를 찾아서 검색
// 배열을 반환
Elements list = doc.select(".book_tit");
if (doc.selectFirst(".no-list") != null) {
break;
}
// Elements images = doc.select(".thumb");
// for (Element e:images) {
// System.out.println(e.attr("src"));
// }
for (Element e : list) {
// 첫번째 자식 Element를 반환
Element a = e.firstElementChild();
// attr로 속성 접근
String link = base + a.attr("href");
String text = a.text();
bookList.add(new NewBook(text, link));
}
// for (int j = 0; j < list.size(); j++) {
// Element a = list.get(j).firstElementChild();
// // 도서 상세 주소
// String link = base + a.attr("href");
// // 도서명
// String text = a.text();
//
// Element image = images.get(j);
// String addr = image.attr("src");
//
// imageDownload(base+addr, text.replaceAll("[/?!@#:'\']", ""));
// System.out.println("이미지 다운 완료");
// bookList.add(new NewBook(text, link));
// }
i++;
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
return bookList;
}
<script>
$(function () {
var arr;
var pageSize = 30; // 한 화면에 보여줄 레코드의 수
var totalRecord;
var totalPage;
var pageGroup = 5; // 한 화면에 보여줄 페이지의 수
// 페이징 그룹화 및 페이징
function printPage(pageNum) {
$("#paging").empty();
var startPage = Math.floor((pageNum - 1) / pageGroup) * pageGroup + 1;
var endpage = startPage + pageGroup - 1;
// 이전 버튼 생성
if (startPage > 1) {
var span = $("<span></span>").html("이전")
.addClass("page").attr("pageNum", startPage - 1);
$("#paging").append(span);
}
for (i = startPage; i <= endpage; i++) {
var span = $("<span></span>").html(i)
.addClass("page").attr("pageNum", i);
$("#paging").append(span);
}
// 다음 버튼 생성
if (endpage < totalPage) {
var span = $("<span></span>").html("다음")
.addClass("page").attr("pageNum", endpage + 1);
$("#paging").append(span);
}
}
// 현재 페이지 번호 맞는 도서30개 가져오기
function loadDate(pageNum) {
// 값을 지우고 넣어야한다
$("#list").empty();
var start = (pageNum - 1) * pageSize;
var end = pageNum * pageSize
if (end > totalRecord) {
end = totalRecord;
}
for (i = start; i < end; i++) {
var book = arr[i];
var title = book.title;
var link = book.link;
var a = $("<a></a>").html(title).attr("href", link);
var li = $("<li></li>");
$(li).append(a);
$("#list").append(li);
}
printPage(pageNum);
}
// 페이징을 위한 함수
/*
function printPage(){
for (i = 1; i <= totalPage; i++) {
var span = $("<span></span>").html(i)
.addClass("page");
$("#paging").append(span);
}
}
*/
$("#paging").on("click", ".page", function () {
var pageNum = eval($(this).attr("pageNum"));
loadDate(pageNum);
});
$.ajax({
url: "/newbook",
success: function (r) {
arr = r;
totalRecord = arr.length;
totalPage = Math.ceil(totalRecord / pageSize);
loadDate(1);
//printPage();
/*
$.each(arr, function(){
var title = this.title;
var link = this.link;
var a = $("<a></a>").html(title).attr("href",link);
var li = $("<li></li>");
$(li).append(a);
$("#list").append(li);
});
*/
}
});
$.ajax({
url:"/getWating",
success: function (r){
$("#wait").html(r);
}
});
});
</script>
이미지 저장 코드
public void imageDownload(String addr, String fname) {
try {
URL url = new URL(addr);
InputStream is = url.openStream();
FileOutputStream fos = new FileOutputStream("C:/data/"+fname+".jpg");
FileCopyUtils.copy(is.readAllBytes(), fos);
is.close();
fos.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
마포평생학습관 자리 사진 주소
http://mpllc-seat.sen.go.kr/seatinfo/Seat_Info/1_count.asp
@GetMapping("/seats")
// public String seats() {
// String r = "";
// try {
// String url = "http://mpllc-seat.sen.go.kr/seatinfo/Seat_Info/1_count.asp";
// Document doc= Jsoup.connect(url).get();
// r = doc.select(".wating_f").get(0).text();
// }catch (Exception e) {
// System.out.println("예외발생:"+e.getMessage());
// }
// return r;
// }
다른 버전 : http://mpllc-seat.sen.go.kr/seatinfo
@GetMapping("/getWating")
public int getWating() {
int cnt = 0;
// String url = "http://mpllc-seat.sen.go.kr/seatinfo/Seat_Info/1_count.asp";
String url = "http://mpllc-seat.sen.go.kr/seatinfo/";
try {
Document doc = Jsoup.connect(url).get();
Elements iframe = doc.select("iframe");
url += iframe.get(0).attr("src");
doc = Jsoup.connect(url).get();
// Elements list = doc.select(".wating_f");
Element e = doc.select(".wating_f").get(0);
cnt = Integer.parseInt(e.text());
System.out.println(cnt);
} catch (Exception e) {
System.out.println(e.getMessage());
}
return cnt;
}