JSP

부트캠프58일차( writeForm에서의 이미지사용 , {jsoupStudy}웹크롤링)

동곤일상 2025. 4. 24. 17:47
반응형

1) model2의 script추가 (writeForm을 위해)

1-1) writeForm수정(글에 이미지업로드를위해)

1-2)  updateForm과 replyForm도 수정

 

2) 웹크롤링

2-1)테이블데이터가져오기(연습)

2-2) 키움히어로즈(야구선수단) 웹에 들어가 선수사진만 가져와보자


1) model2의 script추가 (writeForm을 위해)

해당부분에  밑의 코드 넣자 

summernote를 위해 jqery와 bootstarp의 버전을 바꾸는거임 (기존꺼를 지우지않아도됨)

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.18/summernote.min.js"></script>

 

1-1) writeForm수정(글에 이미지업로드를위해)

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<c:set var="path" value="${pageContext.request.contextPath }" scope="application"></c:set>

<!-- /webapp/view/board/writeForm.jsp -->
<!-- 
	1. boardid가 1인경우 , 관리자가아니면 관리자만 공지사항 글쓰기가 가능합니다
	공지사항 목록 페이지이동
 -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시글등록</title>
</head>
<body>
	<form action="write" method="post" enctype="multipart/form-data"
		name="f">
		<h2 class="text-center">게시판 글쓰기</h2>
		<table class="table">
			<tr>
				<td>글쓴이</td>
				<td><input type="text" name="writer" class="form-control"></td>
			</tr>
			<tr>
				<td>비밀번호</td>
				<td><input type="password" name="pass" class="form-control"></td>
			</tr>
			<tr>
				<td>제목</td>
				<td><input type="text" name="title" class="form-control"></td>
			</tr>
			<tr>
				<td>내용</td>
				<td><textarea rows="15" name="content" id="summernote"
						class="form-control"></textarea></td>
			</tr>
			<tr>
				<td>첨부파일</td>
				<td><input type="file" name="file1"></td>
			</tr>
			<tr>
				<td colspan="2"><a href="javascript:inputcheck()" class="btn btn-outline-secondary">[게시물등록]</a></td>
			</tr>
		</table>

	</form>
	<script type="text/javascript">
		function inputcheck() {
			f = document.f;
			if (f.writer.value == "") {
				alert("글쓴이 입력");
				f.writer.focus();
				return;
			}
			if (f.pass.value == "") {
				alert("비밀번호입력");
				f.pass.focus();
				return;
			}
			if (f.title.value == "") {
				alert("제목입력");
				f.title.focus();
				return;
			}
			f.submit(); //모두아니라면 submit발생 
		}
	</script>
	<%--summernote관련 구현 --%>
<script type="text/javascript">
	$(function(){
		$("#summernote").summernote({ //summernote에디터로변환
			height:300,
			callbacks:{
				//이미지업로드이벤트발생
				//files : 한개이상의 이미지업로드가능(배열)
				onImageUpload : function(files){
					for(let i=0;i<files.length;i++){
						sendFile(files[i]); //하나씩 ajax이용해 서버로파일 전송
					}
				}
			}
		})
	})
	function sendFile(file){
		let data = new FormData(); //폼데이터수집하고 전송가능한 객체, 파일업로드에사용
		data.append("file",file); //이미지파일
		$.ajax({
			//${path}를 사용하기위해서는 layout부분에 path를 설정한곳에 
			//scope="application"추가
			url : "${path}/board/uploadImage", //업로드의기능만가진서블릿
			type:"post",
			data: data, 
			processData : false,
			contentType:false,
			success: function(url){
			//url : 업로드된 이미지의 접근url정보
				$("#summernote").summernote("insertImage",url);
			},
			error : function(e){
				alert("이미지업로드실패 : "+e.status);
			}
		})
	}
</script>
</body>
</html>


 

/java/controller/UploadImageServlet 생성

(servlet파일로 생성할것)

package controller;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

/**
 * Servlet implementation class UploadImageServlet
 */
@WebServlet("/board/uploadImage")
@MultipartConfig //업로드된 파일 처리
public class UploadImageServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       

    public UploadImageServlet() {
        super();
 
    }

    private static final String UPLOAD_DIR = "uploaded_images";
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		Part filePart = request.getPart("file"); //file이름의 데이터를가져옴
		String fileName = getFileName(filePart); //파일명추출
	    String originalFileName = getFileName(filePart);
	    
	    // UUID로 고유한 파일명 생성(중복방지)
	    String savedFileName = UUID.randomUUID().toString() + getFileExtension(originalFileName);
	    
		//file.separator : window : \
		//				   리눅스 : /
		String uploadPath = //파일업로드되는폴더
				//C:/java/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/model2Study/uploaded_images
				getServletContext().getRealPath("")+File.separator+UPLOAD_DIR;
		File uploadDir = new File(uploadPath);
		if(!uploadDir.exists()) {
			uploadDir.mkdirs();
		}
		//filePath  : 이미지파일이 업로드된 절대경로
		String filePath = uploadPath+File.separator+savedFileName;
		filePart.write(filePath);	//파일업로드 @MultipartConfig 필수
		
		//request.getContextPath() : 프로젝트명
		//fileUrl 톰캣이접근할수있는 url정보
		String fileUrl = request.getContextPath()+"/"+UPLOAD_DIR+"/"+savedFileName;
		response.setContentType("text/plain");
		response.getWriter().write(fileUrl); // 클라이언트(summernote)에게 url정보 전달(출력)
	}
	
	private String getFileName(Part part) {
		//content-disposition : form-data; name="file"; filename="iz.jpg"
		System.out.println("content-disposition : "+part.getHeader("content-disposition"));
		for(String content : part.getHeader("content-disposition").split(";")) {
			if(content.trim().startsWith("filename")) {
				return content.substring(content.indexOf("=")+1).trim().replace("\"", "");
				//오직filename만 반환
			}
		}
		return "unkown.jpg";
	}
	// 파일 확장자 추출 메서드
	private String getFileExtension(String fileName) {
	    return fileName.substring(fileName.lastIndexOf("."));
	}

}

 


1-2)  updateForm과 replyForm도 수정

 

둘다 동일하게 가장 상단에 밑에 코드 추가 후

<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<c:set var="path" value="${pageContext.request.contextPath }" ></c:set>

내용을 담는 태그의 id를 summernoter로 변경하자

 

그 후 스크립트에 해당코드 추가

<script type="text/javascript">
	$(function(){
		$("#summernote").summernote({
			height:300,
			callbacks:{
				//onImageUpload : 이미지업로드이벤트발생
				//files : 한개이상의 이미지업로드가능(배열)
				onImageUpload : function(files){
					for(let i=0;i<files.length;i++){
						sendFile(files[i]); //파일 하나씩 ajax이용해 서버로파일 전송
					}
				}
			}
		})
	})
	function sendFile(file){
		let data = new FormData(); //폼데이터수집하고 전송가능한 객체, 파일업로드에사용
		data.append("file",file); //이미지파일
		$.ajax({
			//${path}를 사용하기위해서는 layout부분에 path를 설정한곳에 
			//scope="application"추가
			url : "${path}/board/uploadImage", //업로드의기능만가진서블릿
			type:"post",
			data: data, //data = 전송받은 이미지파일들
			processData : false,
			contentType:false,
			success: function(url){
			//url : 업로드된 이미지의 접근url정보
			//insertImage : image삽입
				$("#summernote").summernote("insertImage",url);
			},
			error : function(e){
				alert("이미지업로드실패 : "+e.status);
			}
		})
	}
</script>

 

 


2)크롤링(jsoup이용)

JsoupStudy라는 이름의 Dynamic프로젝트생성

프로젝트생성 후 ex01_exchange.jsp 생성

 

해당 jar파일을 가져오자

json-simple-1.1.1.zip
0.76MB

 

2-1)  테이블데이터 가져오기

수출입은행 -> 환율정보의 url

 

 

https://www.koreaexim.go.kr/wg/HPHKWG057M01

 

 

/webapp/ex01_exchange.jsp

(자바파일을 사용하려면 꼭 import해줘야함)

(스크립트릿으로사용해도무관하지만 난 자바파일을 따로만들었음)

<%@page import="org.jsoup.select.Elements"%>
<%@page import="java.io.IOException"%>
<%@page import="org.apache.jasper.tagplugins.jstl.core.Catch"%>
<%@page import="org.jsoup.nodes.Element"%>
<%@page import="org.jsoup.nodes.Document"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="org.jsoup.Jsoup" %>
<%@ page import="jsoup.Ex01_exchange" %>
<%--
	1.jsoupStudy 프로젝트생성
	2.ex01_exchange.jsp 생성
	3.3개의 jar파일넣기
	4.브라우저에서 한국수출입은행 사이트에서
	업무안내--> 환율정보 클릭 
	 환율정보url : https://www.koreaexim.go.kr/wg/HPHKWG057M01
	 (주소는 매번바뀔수있음 주의)
 --%>    	
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>수출입은행 환율 정보조회</title>
<style type="text/css">
	table{border-collapse: collapse;}
	table,td,th{border:2px solid grey;}
</style>
</head>
<body>

<%
	/*String url = "https://www.koreaexim.go.kr/wg/HPHKWG057M01";
	String line = "";
	Document doc = null;
	
	try{
		doc = Jsoup.connect(url).get();
		Elements el = doc.select("table");
		for(Element ele  : el){
			String temp = ele.html();
			line += temp;
		}
	}
	catch(IOException e){
		e.printStackTrace();
	} EX01_exchange.java파일로 옮겨놨음
	*/
	String line = Ex01_exchange.Ex01();
%>

<table><%=line %></table>
</body>
</html>

 

/java/jsoup/Ex01_exchange.java

테이블을 통쨰로 크롤링

package jsoup;

import java.io.IOException;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class Ex01_exchange {
	public static String Ex01() {
		String url = "https://www.koreaexim.go.kr/wg/HPHKWG057M01";
		String line = "";
		Document doc = null;
		
		try{
			doc = Jsoup.connect(url).get(); //url접속후 DOM트리 취상위문서
			Elements el = doc.select("table");//doc하위태그중 table태그선택
			for(Element ele  : el){ 
				//ele : table태그 1개
				String temp = ele.html();
				System.out.println(temp);
				line += temp;
				return line;
			}
		}
		catch(IOException e){
			e.printStackTrace();
		}
		return null;
	}
}

 


3-2) 웹크롤링 후 내가 구조를 바꿈


활용예제 ( 수출입 은행 환율정보중 EUR,JPY(100),CNH,USD통화만 출력)

    <%@page import="java.io.IOException"%>
<%@page import="org.jsoup.nodes.Element"%>
<%@page import="org.jsoup.select.Elements"%>
<%@page import="org.jsoup.Jsoup"%>
<%@page import="org.jsoup.nodes.Document"%>
<%@page import="java.util.Arrays"%>
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<%--수출입은행 환율 정보중  EUR,JPY(100),CNH,USD 통화만 
	ex02_exchange.jsp형태로출력--%>
<html>
<head>
<meta charset="UTF-8">
<title>EXAM1</title>
<style type="text/css">
	table{border-collapse: collapse;}
	tabel,td,th{border: 3px solid purple;}
</style>
</head>
<body>
<%
String url = "https://www.koreaexim.go.kr/wg/HPHKWG057M01";
String line = "";
Document doc = null;
List<List<String>> trlist = new ArrayList<List<String>>();
List<String> title = Arrays.asList("전신환받으실때","전신환보내실때","매매기준율","장부가격","중개매매기준율","중개장부 가격");
List<String> list = Arrays.asList("EUR","JPY(100)","CNH","USD");
try{
	doc = Jsoup.connect(url).get(); //DOM트리 최상위문서
	Elements trs = doc.select("tr"); //tr태그들
	for(Element tr : trs) {//tr : tr태그 1개
		List<String> tdlist = new ArrayList<String>();
		Elements tds = tr.select("td"); // td태그들
		for(Element td : tds){ // td : td태그 1개
			tdlist.add(td.html());//td의 내용
			
		}
		//tdlist가 비어있지않고 통화코드가들어있는리스트(list)에 tdlist의0번째인덱스가 존재한다면
		if(tdlist.size()>0 && list.contains(tdlist.get(0))){
			trlist.add(tdlist);
		}
	}
}catch(IOException e) {
	e.printStackTrace();
}
pageContext.setAttribute("trlist", trlist);//el,jstl사용위해 속성등록
pageContext.setAttribute("title", title);
%>
<table>
<c:forEach items="${trlist}" var="tdlist">

	<c:forEach items="${tdlist}" var="td" varStatus="stat">
	
		<c:choose>
			<c:when test="${stat.index % 8 == 0}"> <%--1번쨰 td(통화코드) --%>
				<tr><td rowspan="6">${td}</td>
			</c:when>
			<c:when test="${stat.index % 8 == 1}"><%--2번쨰 td(통화명) --%>
				<td rowspan="6">${td}</td>
			</c:when>
			<c:when test="${stat.index % 8 == 2}"><%--3번쨰 td : 전신환받으실때의 환율 --%>
				<td>${title[0]}</td><td>${td}</td></tr>
			</c:when>
			<c:otherwise>
				<tr><td>${title[stat.index -2]}</td><td>${td}</td></tr>
			</c:otherwise>
		</c:choose>
	</c:forEach>
</c:forEach>
</table>

</body>
</html>


2-2) 키움히어로즈(야구선수단) 웹에 들어가 선수사진만 가져와보자

해당사이트임

https://heroesbaseball.co.kr/players/infielder/list.do

 

선수단

 

heroesbaseball.co.kr


 

크롤링코드

/webapp/exam2_Img.jsp

    <%@page import="org.apache.catalina.tribes.transport.MultiPointSender"%>
<%@page import="java.io.IOException"%>
<%@page import="org.jsoup.nodes.Element"%>
<%@page import="org.jsoup.select.Elements"%>
<%@page import="org.jsoup.Jsoup"%>
<%@page import="org.jsoup.nodes.Document"%>
<%@page import="java.util.Arrays"%>
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>이미지추출</title>
<style type="text/css">
	img{
		border:30px;
		width:100px;
		height:100px;
	}
td{
	border: 1px solid purple;
	width:200px;
}
</style>
</head>
<body>
<%
	String url = "https://heroesbaseball.co.kr/players/infielder/list.do";
	Document doc = null;
	List<String> html = new ArrayList<>();
	try{
		doc = Jsoup.connect(url).get(); //최상위DOM트리 최상위문서
		Elements ele = doc.select("a"); // a태그들 꺼내기
		for(Element el : ele){
			//id가position인 태그가져와
			Element positionElement = el.select(".position").first();
			//태그가있고 태그내의 이름이 내야수인 태그만!!!!
			if(positionElement!=null && positionElement.text().equals("내야수")){
				Elements img = el.select("img");//img태그들
				for(Element im : img){
					if(img!=null){
						String ab = im.absUrl("src");//src를 가져와 절대경로로바꿈	          
		                img.attr("src", ab); // 바꾼경로를 해당 src에 넣음
					}
				}
				html.add(el.html()); // a태그의 html을 List에넣기
				
			}
		}
	}
	catch(Exception e){
		e.printStackTrace();
	}
	request.setAttribute("list",html);
	
%>

<table>
<tr>
<c:forEach items="${list}" var="s" varStatus="i">
<td>${s}</td>
<c:if test="${i.count%4==0}"></tr><tr></c:if>
</c:forEach>
</tr>
</table>
</body>
</html>

다음과같이 정보를 가져왔음

 


3) 나만의 예제

해당사이트의 사진들을 모두 가져와볼게요

 

Nareum.java

package jsoup;

import java.util.ArrayList;
import java.util.List;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class Nareum {
	public static List<String> nareum() {
		String url = "https://nareum.co.kr/product/list.html?cate_no=28";
		Document doc = null;
		ArrayList<String> list = new ArrayList<>();
		try {
			doc = Jsoup.connect(url).get();
			Elements div= doc.select("img");
			for (Element im : div) {
				if(im!=null ) {
					String src = im.absUrl("src");
					System.out.println(src);
					if(!src.contains("wish") && !src.contains("cate_no")) {
						list.add(src);
					}
				}
			}
			return list;
		}
		catch(Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}

nareum.jsp

<%@page import="java.util.List"%>
<%@page import="jsoup.Nareum"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>    
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
	img{
		height:100px;
		width:100px;
	}
	td{
		width:50px;
	}
</style>
<meta charset="UTF-8">
<title>나름SHOP</title>
</head>
<body>
<%
	List<String> list = Nareum.nareum();
	request.setAttribute("list", list);

%>

<table>
<tr>
<c:forEach items="${list}" var="s" varStatus="i">
<td><img src="${s}"></td>
<c:if test="${i.count%8==0}"></tr><tr></c:if>
</c:forEach>
</tr>
</table>

</body>
</html>