23.04.13

이준영·2023년 4월 14일
0

🍇

  • OpenAPI - 공식제공 : 회원가입 (api key)
  1. text 형식
    CSV : ,로 split되는 내용들

    XML(extensible markup language) : HTML을 획기적으로 개선하여 만든 언어

    JSON(Javascript Object Notation) : 키와 값 중심으로, 객체의 표기법 중 하나(new가 자동으로 돼서 나옴) (jsonlint.com 참조 = JSON 검사기)
    JSON은 {} = 객체 [] =배열 이해만 하면 된다.

=> 1. String , StringBuffer / StringBuilder / 2.Library 통하여 분석



2. Library(API) 형식


  • 비공식 제공 : html(image) - 크롤링(스크래핑)
  1. String , StringBuffer / StringBuilder
  2. Regular Expression(POSIX) - 특정한 규칙을 가진 문자열의 집합 표현(주로 문자열 검색 / 치환 용도)
  3. Library(API) - JSoup
    => 이것들로 가공



🍇 한 줄로 된 데이터 가공하기 (XML)

직접 가져오는 것이 아닌 웹서버가 공개했기 때문에 웹서버를 통해 가져오는 것이다.


  1. URLConnection 으로 가공
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class parsing1 {

	public static void main(String[] args) {
		// Parsing = 문서 분석
		BufferedReader br = null;
		try {
        	//영화 주간 박스 사이트 정보 가져옴
			URLConnection conn = new URL("http://kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchWeeklyBoxOfficeList.xml?key=f5eef3421c602c6cb7ea224104795888&targetDt=20230408").openConnection();
			br = new BufferedReader(new InputStreamReader(conn.getInputStream()));

			//이 사이트의 데이트는 한 줄이기 때문에 while 할 필요 없음
			String line = br.readLine();

			boolean flag = false;
			
			//데이터의 공통된 부분 찾아서 엔터키 넣어주기 
			line = line.replaceAll("><", ">\n<");
			
            //split으로 배열 형식으로 나누기
			String[] lines = line.split("\n");
			
			for(String data : lines) {
			if(data.trim().startsWith("<rank>") ) {
				System.out.println(
						data.trim()
						.replaceAll("<rank>", "")
						.replaceAll("</rank>", "")); //replaceAll은 앞뒤 랭크 지우기 위함
			}
			if(data.trim().startsWith("<movieNm>") ) {
				System.out.println(
						data.trim()
						.replaceAll("<movieNm>", "")
						.replaceAll("</movieNm>", "")); // " "
			}
			}
			
			
			
		} catch (MalformedURLException e) {
			System.out.println("[에러] : " + e.getMessage());
		} catch (IOException e) {
			System.out.println("[에러] : " + e.getMessage());
		} finally { 
			if(br != null) try { br.close(); } catch(IOException e) {}
		}
	}
}


2.JSoup으로 가공 ( 훨씬 간편 )

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

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

public class parsing2 {

	public static void main(String[] args) {
		// Parsing = 문서 분석
		BufferedReader br = null;
		try {
			URLConnection conn = new URL("http://kobis.or.kr/kobisopenapi/webservice
            /rest/boxoffice/searchWeeklyBoxOfficeList.xml?
            key=f5eef3421c602c6cb7ea224104795888&targetDt=20230408").openConnection();
			br = new BufferedReader(new InputStreamReader(conn.getInputStream()));

			//이 사이트의 데이트는 한 줄이기 때문에 while 할 필요 없음
			String data = br.readLine();
			
			Document doc = Jsoup.parse(data);
			
			
			Elements rankTags = doc.getElementsByTag("rank"); 
			Elements nameTags = doc.getElementsByTag("movieNm");
			
			for(int i = 0; i < rankTags.size(); i++) {
				Element rankTag = rankTags.get(i);
				System.out.println(rankTag.text());

				Element nameTag = nameTags.get(i);
				System.out.println(nameTag.text());

			}
			
		} catch (MalformedURLException e) {
			System.out.println("[에러] : " + e.getMessage());
		} catch (IOException e) {
			System.out.println("[에러] : " + e.getMessage());
		} finally { 
			if(br != null) try { br.close(); } catch(IOException e) {}
		}
	}

}



🍇 응용 : 영화 정보 추출하기 (XML)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

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

public class parsing3 {

	public static void main(String[] args) {
		// Parsing = 문서 분석
		BufferedReader br = null;
		try {
			URLConnection conn = new URL("http://www.kobis.or.kr/kobisopenapi/webservice/
            rest/movie/searchMovieInfo.xml?
            key=f5eef3421c602c6cb7ea224104795888&movieCd=20124079").openConnection();
            
           
			br = new BufferedReader(new InputStreamReader(conn.getInputStream()));

			//이 사이트의 데이트는 한 줄이기 때문에 while 할 필요 없음
			String data = br.readLine();
			
			Document doc = Jsoup.parse(data);
			
			Elements cdTags = doc.getElementsByTag("movieCd");
			Elements nmTags = doc.getElementsByTag("movieNm");
			Elements acTags = doc.getElementsByTag("actor");
			Elements ppTags = doc.getElementsByTag("peopleNm");
			
			
			System.out.println(cdTags);
			System.out.println(nmTags);
			
			for(int j = 0; j < acTags.size(); j++) {
				Element acTag = acTags.get(j);
				Element ppTag = ppTags.get(j);
				if(acTag != null)
				System.out.println(ppTag.text());
			}
			
		} catch (MalformedURLException e) {
			System.out.println("[에러] : " + e.getMessage());
		} catch (IOException e) {
			System.out.println("[에러] : " + e.getMessage());
		} finally { 
			if(br != null) try { br.close(); } catch(IOException e) {}
		}
	}
}



🍇 라이브러리 사용하여 JSON 데이터 가져오기

직접 가져오는 것이 아닌 웹서버가 공개했기 때문에 웹서버를 통해 가져오는 것이다.

🍇 정수형이나 문자열 가져오기

정수형

import org.json.simple.JSONArray;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

public class JSon1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String strJson= "[8, 9, 6, 2, 9]";
		
		JSONParser parser = new JSONParser();
		
		try {
			JSONArray array = (JSONArray)parser.parse(strJson);
			
			//배열 형식으로 전체 리스트
			System.out.println(array);
			//System.out.println(array.size());
			
			//하나씩 출력
			for(int i = 0;  i < array.size(); i++) {
				//json 기본 정수형 = long
				long data = (Long)array.get(i);
				System.out.println(data);
			}
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}



문자열

문자열은 위 코드에서 선언부랑 반복문쪽 변수 타입만 바꾸고 나머지는 동일하다.

	String strJson= "[\"8\", \"9\", \"6\", \"2\", \"9\"]";
    
    
    for(int i = 0;  i < array.size(); i++) {
				
				String data = (String)array.get(i);
				System.out.println(data);
			}


🍇 객체 가져오기

import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

public class JSon2 {

	public static void main(String[] args) {
		//객체는 시작점이 중괄호
		String strJson= "{\"data1\" : \"value1\" , \"data2\" : \"value2\"}";  <--객체로 생성
		
		JSONParser parser = new JSONParser();
		
		try {
			JSONObject obj = (JSONObject)parser.parse(strJson);
			
			String data1 = (String) obj.get("data1"); <-- data1에 대한 값 가져옴
			System.out.println(data1);

			String data2 = (String) obj.get("data2"); <--data2에 대한 값 가져옴
			System.out.println(data2);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}


🍇 배열 / 객체로 이루어진 것 가져오기

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

public class JSon4 {

	public static void main(String[] args) {
		//문자형은 항상 ""
		//[] = 동종 데이터 넣어주기
		String strJson = "[{\"name\" : \"홍길동\", \"city\" : \"서울\"}, 
        {\"name\" : \"박문수\", \"city\" : \"경기\"}]";  <-- 차례대로 추출하기
		
		JSONParser parser = new JSONParser();
		
		try {
			JSONArray arr = (JSONArray)parser.parse(strJson);
			
			System.out.println(arr.size());
			
			for(int i = 0; i<arr.size(); i++) {
			JSONObject object = (JSONObject)arr.get(i);
			
			String name = (String)object.get("name");
			
			System.out.println(name);
			
			String city = (String)object.get("city");
			
			System.out.println(city);
			}
			
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}



🍇 응용 : 영화 정보 JSON으로 가져오기

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

public class parsing4 {

	public static void main(String[] args) {
		// Parsing = 문서 분석
		BufferedReader br = null;
		try {
			URLConnection conn = new URL(
					"http://kobis.or.kr/kobisopenapi/webservice/
                    rest/boxoffice/searchWeeklyBoxOfficeList.json?
                    key=f5eef3421c602c6cb7ea224104795888&targetDt=20230408")
					.openConnection();
			br = new BufferedReader(new InputStreamReader(conn.getInputStream()));

			String line = br.readLine();

			//차례대로 분리할 것
			JSONParser parser = new JSONParser();
			
			JSONObject root = (JSONObject) parser.parse(line);
			
			JSONObject boxOfficeResult  = (JSONObject) root.get("boxOfficeResult");
			JSONArray weeklyBoxOfficeList = (JSONArray) boxOfficeResult.get("weeklyBoxOfficeList");
			
			for(int i = 0; i < weeklyBoxOfficeList.size(); i++) {
				JSONObject weeklyBoxOffice = (JSONObject) weeklyBoxOfficeList.get(i);
				System.out.printf("%s\t%s\t%s\n",
						weeklyBoxOffice.get("rank"),
						weeklyBoxOffice.get("movieCd"),
						weeklyBoxOffice.get("movieNm"));
			}
			

		} catch (ParseException e) {
			System.out.println("[에러] : " + e.getMessage());
		} catch (MalformedURLException e) {
			System.out.println("[에러] : " + e.getMessage());
		} catch (IOException e) {
			System.out.println("[에러] : " + e.getMessage());
		} finally {
			if (br != null)
				try {
					br.close();
				} catch (IOException e) {
				}
		}
	}
}



🍇 Socket

ServerSocket - 제공자용 소켓 (여기에 Socket이 연결되는 것, 여러개 가능)

  1. 전송규약

  2. 몇 번 포트로 열지

  • TCP(Transmission Control Protocol)
    전화라고 생각(상호 동작 이뤄지는 것)
    확인/응답이 가장 중요 / 속도가 느리다
    Http

ServerSocketd 이용하여 제공 정보 만들고, Socket을 통하여 접근!
(받는쪽 보내는쪽 같이 짜야한다. 이클립스, cmd 같이 사용)



  • UDP(User Diagram Protocol)
    방송이라고 생각(일방적으로 뿌리는 것)
    확인하지 않음

가 중요하다.




🍇 서버 접속을 위한 코드

package pack1;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPServer1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ServerSocket serverSocket = null;
		Socket socket = null;
		
		//1개의 포트는 1개의 프로그램만 사용 가능
		try {
			//포트 생성
			serverSocket = new ServerSocket(7777);
			System.out.println("서버가 준비되었습니다.");
			
			//대기하는것
			socket = serverSocket.accept();
			System.out.println("클라이언트가 연결되었습니다.");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if(socket != null) try { socket.close(); } catch(IOException e) {}
			if(serverSocket != null) try { serverSocket.close(); }
            }

🍇 클라이언트 코드

package pack1;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

public class TCPClient1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Socket socket = null;
		System.out.println("서버와 연결을 시작합니다.");
		try {
			socket = new Socket("localhost", 7777);
			System.out.println("서버와 연결되었습니다");
		} catch (UnknownHostException e) {
			System.out.println("[에러]:" + e.getMessage());

		} catch (IOException e) {
			System.out.println("[에러]:" + e.getMessage());
		} finally {
			if(socket != null) try { socket.close(); } catch(IOException e) {}
		}
	}

}

cmd에서 서버 실행

후에 클라이언트에서 실행



🍇 서버에서 쓰고 클라이언트에서 쓴 내용 받기

서버에서 bufferedWriter (여러개 쓰고 싶으면 받을 때도 여러개 받아줘야 한다, 좋은방식은 아님)

package pack2;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPServer1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ServerSocket serverSocket = null;
		Socket socket = null;
		
		BufferedWriter bw = null;
		
		//1개의 포트는 1개의 프로그램만 사용 가능
		try {
			//포트 생성
			serverSocket = new ServerSocket(7777);
			System.out.println("서버가 준비되었습니다.");
			
			//대기하는것
			socket = serverSocket.accept();
			System.out.println("클라이언트가 연결되었습니다.");
			
			//소켓에 다국어 기능도 전송하기 위해서 bufferedWriter 추가
			bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
			bw.write("Hello Client" + System.lineSeparator());
			
			System.out.println("전송이 완료되었습니다.");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if(socket != null) try { socket.close(); } catch(IOException e) {}
			if(serverSocket != null) try { serverSocket.close(); } catch(IOException e) {}
			if(bw != null) try { bw.close(); } catch(IOException e) {}
		}
	}
}

클라이언트에서 bufferedReader

package pack2;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

public class TCPClient1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Socket socket = null;
		System.out.println("서버와 연결을 시작합니다.");
		
		BufferedReader br = null;
		try {
			socket = new Socket("localhost", 7777);
			System.out.println("서버와 연결되었습니다");
			
			//서버에서 만든 것 받을 용도
			br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			
			System.out.println("메시지 : " + br.readLine());
		} catch (UnknownHostException e) {
			System.out.println("[에러]:" + e.getMessage());

		} catch (IOException e) {
			System.out.println("[에러]:" + e.getMessage());
		} finally {
			if(socket != null) try { socket.close(); } catch(IOException e) {}
			if(br != null) try { br.close(); } catch(IOException e) {}
		}
	}

}


반대로 하면 역할이 반대가 됨
(한글을 넣으면 윈도우 시스템 인코딩이 안맞아서 깨져나옴)

bufferedReader / Writer 쓸 때 연결하고 뒤에 utf-8을 서로 써주면 해결된다.

			br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf-8"));


			bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "utf-8"));

순차적으로 생각!



🍇 구분자를 내가 만들어서 여러 개의 데이터 보내기

보낼 때 구분자를 통하여 합쳐서 만들고

bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "utf-8"));
			//전송 프로토콜
			bw.write("안녕 서버1:안녕 서버2:안녕 서버3" + System.lineSeparator());

받을때 구분자로 나눠서 실행한다.

br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf-8"));
			
			String[] arr = br.readLine().split(":");
			
			for(String arrs : arr) {
				System.out.println(arrs);



🍇 echo = 클라이언트가 던지면 그대로 다시 리턴해줌

받고 던지기 때문에 br->bw 순으로 선언

서버


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPServer1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ServerSocket serverSocket = null;
		Socket socket = null;
		
		BufferedReader br = null;
		BufferedWriter bw = null;
		
		//1개의 포트는 1개의 프로그램만 사용 가능
		try {
			//포트 생성
			serverSocket = new ServerSocket(7777);
			System.out.println("서버가 준비되었습니다.");
			
			socket = serverSocket.accept();
			System.out.println("클라이언트가 연결되었습니다.");
			
			br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf-8"));
			bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "utf-8"));
			
			String msg = br.readLine();
			System.out.println("메세지 : " + msg);
			
			bw.write(msg + System.lineSeparator());
			
			//전송 완료
			bw.flush();
			System.out.println("전송이 완료되었습니다.");
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if(bw != null) try { bw.close(); } catch(IOException e) {}
			if(br != null) try { br.close(); } catch(IOException e) {}
			if(socket != null) try { socket.close(); } catch(IOException e) {}
			if(serverSocket != null) try { serverSocket.close(); } catch(IOException e) {}
		}
	}
}

클라이언트

package pack4;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class TCPClient1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Socket socket = null;
		System.out.println("서버와 연결을 시작합니다.");
		
		BufferedWriter bw = null;
		BufferedReader br = null;
		
		try {
			socket = new Socket("localhost", 7777);
			System.out.println("서버와 연결되었습니다");
			
			bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "utf-8"));
			br = new BufferedReader(new InputStreamReader(socket.getInputStream(),"utf-8"));
			
			bw.write("Hello Echo Server" + System.lineSeparator());
			
			bw.flush();
			System.out.println("전송이 완료되었습니다.");
			
			String msg = br.readLine();
			System.out.println("에코메세지 : " + msg);
			
		} catch (UnknownHostException e) {
			System.out.println("[에러]:" + e.getMessage());

		} catch (IOException e) {
			System.out.println("[에러]:" + e.getMessage());
		} finally {
			if(br != null) try { br.close(); } catch(IOException e) {}
			if(bw != null) try { bw.close(); } catch(IOException e) {}
			if(socket != null) try { socket.close(); } catch(IOException e) {}
		}
	}

}

서버 연결 후 클라이언트에서 메세지를 날리고 다시 날려주는 모습



🍇 서버 - 클라이언트 echo 모드로 구구단 출력하기

  1. 클라이언트에서 특정 단수 써서 서버에 보내줌
  2. 서버에서 해당 단수 받고 구구단 로직 써준 후에 다시 클라이언트에 보내줌
  3. 서버 연결 후 클라이언트에서 읽어서 실행

서버

package pack1;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPServer1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ServerSocket serverSocket = null;
		Socket socket = null;
		
		BufferedReader br = null;
		BufferedWriter bw = null;
		
		try {
			serverSocket = new ServerSocket(7777);
			System.out.println("서버가 준비되었습니다.");
			
			socket = serverSocket.accept();
			System.out.println("클라이언트가 연결되었습니다.");
			
			br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf-8"));
			bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"utf8"));
			
			int msg = br.read();
			
			
			for(int i = msg; i == msg; i++) {
				for(int j = 1; j <= 9; j++) {
					bw.write(i + " x " + j + " = " + (i * j) + System.lineSeparator());
				}
			}
			
			bw.flush();
			System.out.println("전송 완료");
			
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if(bw != null) try { bw.close(); } catch(IOException e) {}
			if(br != null) try { br.close(); } catch(IOException e) {}
			if(socket != null) try { socket.close(); } catch(IOException e) {}
			if(serverSocket != null) try { serverSocket.close(); } catch(IOException e) {}
		}
	}
}

클라이언트

package pack1;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class TCPClient {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Socket socket = null;
		
		BufferedWriter bw = null;
		BufferedReader br = null;
		
		System.out.println("서버와 연결을 시작합니다.");
		
		try {
			socket = new Socket("localhost", 7777);
			System.out.println("서버와 연결되었습니다.");
			
			bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"utf8"));
			br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf-8"));
			
			bw.write(2);
			
			bw.flush();
			System.out.println("전송 완료");
			
			String gugudan = null;
			
			while((gugudan = br.readLine())!= null) {
			System.out.println(gugudan);
			}
			
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if(br != null) try { br.close(); } catch(IOException e) {}
			if(bw != null) try { bw.close(); } catch(IOException e) {}
			if(socket != null) try { socket.close(); } catch(IOException e) {}
		}
		
	}

}

profile
끄적끄적

0개의 댓글