[문제링크]

 

16946번: 벽 부수고 이동하기 4

N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 한 칸에서 다른 칸으로 이동하려면, 두 칸이 인접해야 한다. 두 칸이

www.acmicpc.net

 

0. 사방 처리를 위해 외곽을 1로 감쌌다

 

1. 전체를 탐색하면서 0, 빈공간을 만날 경우 BFS 진행

  - BFS에서 거쳐가는 모든 칸을 index로 칠해 재탐색 방지 + 추후 이용

  - BFS의 결과로 반환된 size를 ArrayList에 저장한다

  - ( 0은 빈칸, 1은 벽이므로 area index는 2부터 시작, index 유지를 위해 0 2개 삽입)

 

2. 전체를 탐색하면서 벽을 만날 경우 4방향에 대해

  - 1이 아니면 빈 공간이 index로 칠해진 것. 해당 index의 size를 ArrayList로부터 가져와 누적한다.

  - 1이면 벽, 무시한다

 

3. 각 방향의 area index가 같다면, 두번 더해선 안된다.

  - 4개의 값이므로, 각각 이전 값들과 다를 경우에만 누적한다 ( 가독성, 확장성은 좋지 않지만, 성능 효율적 )

  - set에 다 던져넣고 하나씩 꺼내며 쓴다 ( 가독성, 확장성은 좋지만, 성능 비효율적)

 

4. 출력할 때 println등을 이용하면 최악 1000*1000번 출력하게되므로, buffer 이용이 필수적이다

 

+ 4번 print구간은 3번 반복문에 그대로 삽입할 수 있다

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class Main{
	public static void main(String[] args)throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringBuilder sb = new StringBuilder();
		
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		int n = pint(st.nextToken());
		int m = pint(st.nextToken());
		
		map=new int[n+2][m+2];
		int[][]ansMap=new int[n+2][m+2];
		//외곽 padding
		for (int i = 0; i < n+2; i++) {
			map[i][0]=1;map[i][m+1]=1;
		}
		for (int i = 0; i < m+2; i++) {
			map[0][i]=1;map[n+1][i]=1;
		}
		// 1. input
		for (int i = 1; i <= n; i++) {
			String s = br.readLine();
			for (int j = 1; j <= m; j++) {
				map[i][j]=s.charAt(j-1)-'0';
			}
		}
		//2. get size by bfs for each area + tagging
		ArrayList<Integer>area=new ArrayList<>();
		area.add(0);area.add(0);
		int idx=2;
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				if(map[i][j]==0) {
					int size=search(idx++, i, j);
					area.add(size);
				}
			}
		}
		//3. check four-dir of each wall + add if area
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				if(map[i][j]==1) {
					ansMap[i][j]+=1;
					if(map[i+1][j]!=1)
						ansMap[i][j]+=area.get(map[i+1][j]);
					if(map[i][j+1]!=1 && map[i+1][j]!=map[i][j+1])
						ansMap[i][j]+=area.get(map[i][j+1]);
					if(map[i-1][j]!=1&& map[i+1][j]!=map[i-1][j] && map[i-1][j]!=map[i][j+1])
						ansMap[i][j]+=area.get(map[i-1][j]);
					if(map[i][j-1]!=1 && map[i][j-1]!=map[i+1][j]&& map[i][j-1]!=map[i][j+1] && map[i][j-1]!=map[i-1][j])
						ansMap[i][j]+=area.get(map[i][j-1]);
				}
			}
		}
		//4.print
		for (int i = 1; i < n+1; i++) {
			for (int j = 1; j < m+1; j++)sb.append(ansMap[i][j]%10);
			sb.append("\n");
		}System.out.println(sb);
	}
	static int[][]map;
	static int search(int idx, int x, int y) {
		int size=1;
		map[x][y]=idx;
		if(map[x+1][y]==0)size+=search(idx,x+1,y);
		if(map[x-1][y]==0)size+=search(idx,x-1,y);
		if(map[x][y+1]==0)size+=search(idx,x,y+1);
		if(map[x][y-1]==0)size+=search(idx,x,y-1);
		return size;
	}
	
	static int pint(String s) {
		return Integer.parseInt(s);
	}
}

결과 화면 ( Hashset 미사용/사용 )

 

'알고리즘 문제 풀이 > BOJ 골드' 카테고리의 다른 글

[백준] 10942 - 팰린드롬?  (0) 2021.05.19
[백준] 16724 - 피리 부는 사나이  (0) 2021.05.16
[백준] 1068 - 트리  (0) 2021.05.14
[백준] 20040 - 사이클 게임  (0) 2021.05.05
[백준] 1062 - 가르침  (0) 2021.05.05
[백준] 17404 - RGB거리 2  (0) 2021.05.02
[백준] 10775 - 공항  (0) 2021.05.01

  Twitter4j로 웹에서 자동으로 트윗할 수 있도록 하는 기능을 만들려고 했는데, 검색결과가 2015년 이후로는 거의 없다시피 하고, pin방식은 아예 없어서 작성해봅니다.

 

1. 트위터 앱 생성과 키 발급

 

  우선 앱이 있어야 사용자가 인증을 받을 수 있습니다

트위터_개발자_계정_취득하기 (2021년 글)

트위터_API_사용_준비 (2020년 글, 일부 UI의 차이)

 

  자세히 설명해 둔 블로그로 이 부분은 설명을 대체하겠습니다.

  *2021년들어 인증 절차가 까다로워졌다는 말이 있던데, 저는 정직하게 '내 서비스랑 연동해서 자동 트윗하는 봇 만들꺼다' 하고 보냈더니 별 추가 절차 없이 통과되었습니다. 

 

  개발자 계정을 잘 발급 받으시고, projects / app까지 생성하시면 다음과 같은 항목을 보실 수 있습니다.

  

  Access Token이 없으시면 APP - Keys and Tokens에서 발급받으시면 됩니다.

  모든 항목은 단 한번만 보여지며, 재발급시엔 기존 토큰들이 날아가는 듯 하니 어딘가 저장해놓고 사용하는게 좋겠습니다.

 

  Access Token을 이용하면, 트위터 로그인 과정 없이도 자바 코드상에서 인증받고, 트윗을 쓰고, RT하고, 답글을 다는 등 트위터 이용이 가능합니다.

 

  하지만 이 때 사용되는 계정은 app을 생성한 개발자 계정입니다. 지금 저는 봇계정을 만들어 그쪽에서 자동으로 트윗되도록 하고 싶은 상황이니, 본 계정을 사용할 수 있다고 해도 별 소용이 없습니다.

 

  이럴때 사용하는 게 위의 Consumer key / secret입니다. 이 값들로 우리는 다른 계정에게 Access Token 요청을 보낼 수 있으며, 요청이 수락되면 그 계정의 Access Token을 얻어 조작할 수 있게 되죠.

 

익숙한 이미지

  트위터 앱 승인 함부로 하면 안된다는 이유가 이겁니다. ID / PW가 해킹당하지 않더라도 재미있는 서비스 앱을 승인해줬는데 어느순간 내 계정에 광고가 올라오는 상황이 발생할 수 있는 것이죠.

 

  이만 각설하고, Consumer key / secret으로 다른 계정의 Access Token 획득 방법에 대해 알아보겠습니다.

 

2. 해당 키로 인증해 pin 발급받기

 

  우선, JAVA에서 twitter 서비스를 사용할 수 있게 해주는 라이브러리를 추가해야 합니다.

  twitter4j 다운받기

  

  여러 jar 파일 중 twitter4j-core-x.x.x파일만 사용해도 충분합니다

 

  우선 위에서 취득한 Consumer key / secret을 이용해 사용자에게 앱 인증 요청을 보내야합니다.

 

//전역변수 선언
static String accessToken="";
static String accessSecret="";
	
static Twitter twitter;
RequestToken requestToken=null;
AccessToken finalAccessToken=null;

//twitter 객체 초기화 + consumer 인증 set
twitter = TwitterFactory.getSingleton();
twitter.setOAuthConsumer(TwitterInfo.getInstance().getAPIKey(), 
		TwitterInfo.getInstance().getAPISecretKey());

  twitter 객체를 획득한 후, setOAuthConsumer 함수를 이용해 Consumer의 key와 secret을 설정합니다.

  해당 함수는 2번째 실행부터는 에러가 발생한다고 하는데, singleton 패턴이 적용된 생성자 내부에서 실행하여 에러 발생을 막았습니다.

 

twitter = TwitterFactory.getSingleton();
		
requestToken=null;
try {
	requestToken = twitter.getOAuthRequestToken();
}catch(TwitterException e) {
	e.printStackTrace();
}
System. out.println(requestToken.getAuthorizationURL());
        

  그 후 getOAuthRequestToken() 함수를 이용해 requestToken을 획득합니다.

  requestToken.getAuthorizationURL() 의 값이 인증 URL입니다. 서버라면 이 주소로 redirect되도록 할 수 있습니다.

 

  그 후는 사용자가 트위터 계정을 로그인하고, 앱 사용 승인버튼을 눌러주면 됩니다.

 

3. pin으로 인증해 최종 accesstoken받기

 

  원래는 사용자가 승인버튼을 누르면, 인증정보를 담은 채 본래 인증창이 비롯된 페이지로 되돌아간다고 합니다.

  하지만 따로 돌아갈 url을 지정해놓지 않았거나, 저처럼 호스팅되지 않은 서버에서 온 요청같은 경우 이 방법은 사용할 수 없습니다.

 

  그래서 트위터는 7자리 숫자 pin을 제공하며, 서비스에서 해당 pin으로 다시 요청을 보내면 그 때 accessToken을 발급해 줍니다.

  대충 맨날 하는 문자인증과 비슷하다고 보시면 될 듯 합니다.

 

  처리 방법도 문자인증 방법과 비슷합니다. client에게 네가 받은 그 정보를 다시 나에게 달라고 요청하는 것이죠.

  (물론 제 경우는 서버도 client도 같은 시스템이므로 어떻게든 우겨넣기만 하면 상관없긴 합니다)

 

public void tweetGetAccessTokenTest(String pin) {
	try {
		finalAccessToken = twitter.getOAuthAccessToken(requestToken, pin);
	}catch(TwitterException e) {
		e.printStackTrace();
	}
}

  그렇게 받은 pin 정보는, 이전에 취득했던 requestToken과 함께 다시 한번 트위터에게 제출됩니다.

  getOAuthAccessToken함수를 이용합니다.

 

  이 과정까지 성공적으로 완료했다면, 정상적으로 AccessToken을 획득한 것으로 이제 이 계정은 제 맘대로 할 수 있는 겁니다. (안됩니다)

 

twitter.setOAuthAccessToken(finalAccessToken);
	try {
    	//계정명 획득
		User user = twitter.verifyCredentials();
		System.out.println(user.getScreenName());
		
        //계정에 트윗 등록
		String msg = "this is test tweet from application";
		Status status = twitter.updateStatus(msg);		
	}catch(Exception e) {
		e.printStackTrace();
}

정상적으로 출력 / 트윗되었다

  다음 코드와 같이, AccessToken을 Set해주기만 하면 사용자 ID를 가져올 수도 있고, 원하는 문자열로 트윗을 보낼 수도 있습니다.

 

4. AccessToken을 저장해 둬 재사용 가능하게 하기

 

  여기까지만 하면, 매번 AccessToken을 획득해야한다는 수고로운 일이 생깁니다.

  물론 그럴 필요는 없습니다. AccessToken만 저장해두면 언제든지 꺼내서 재사용이 가능해집니다.

 

  위에서 획득한 AccessToken은 Consumer key/secret처럼 key/secret 두가지 token으로 되어 있습니다.

  getToken() 함수와, getTokenSecret()함수가 각 token을 획득 할 수 있으며, 플젝에 직접 박아놓든, DB에 저장하거나 한 후 필요할 때 조회하면 됩니다.

 

twitter = TwitterFactory.getSingleton();
finalAccessToken=new AccessToken(TwitterInfo.getInstance().getAccessToken(), 
		TwitterInfo.getInstance().getAccessSecret());

twitter.setOAuthAccessToken(finalAccessToken);




try {
	User user = twitter.verifyCredentials();
	System.out.println(user.getScreenName());
	
	String msg = "this is test tweet from application";
	Status status = twitter.updateStatus(msg);
}catch(Exception e) {
	e.printStackTrace();
}

  저는 TwitterInfo class에 값을 직접 저장했으며, consumer token과 함께 생성자에서 호출해 설정하는 식으로 마무리했습니다.

 

 

  이상으로 twitter4j를 이용한 트위터 인증 획득 방법을 마치겠습니다.

 

<한줄요약>

JQuery : CSS생성자를 기반으로 DOM 조작 / event처리를 간편히 하는 JS 라이브러리

 

1. JQuery란?

 

-  CSS생성자를 사용, 기본 JS보다 간편하게 DOM/이벤트 처리 가능

-  모든 브라우저에서 동일하게 동작, 호환성 고려할 필요가 없음

-  Event, Ajax를 쉽게 사용 가능

 

 

2. JQuery 기본 구문

 

-  CSS의 selector를 사용해 DOM을 탐색, 반환값으로 함수 수행

-  $(selector).action(); 의 구조이다.

-  DOM 탐색 전에 문서가 다 로드되어 있어야 한다

-  $(document).ready(function() {   });

-  $(function() {  });

-  2가지 방법으로 문서 로드 후 시작 가능

<script>
	$(document).ready(function() {
    	$(".button").click(function(){
        	$("#id").css("background", "orange");
        });
    });

</script>

-  .button class를 가지는 element 클릭시, #id id를 가지는 element의 css를 변경

 

-  css의 속성 선택자도 똑같이 이용 가능하다

-  $(selector[attr="value"]).action();

 

 

3. JQuery 선택자

 

-  css의 선택자 외에 추가된 선택자

 

-  필터 선택자

-  DOM 탐색한 결과 중 원하는 요소를 찾기 위해 사용

선택자 선택 요소
button input type="button" 혹은 button 태그
image, password, radio, reset 등 input의 type요소 type="~"인 input
checked 체크된 form
disabled 비활성화된 form
enabled 활성화된 form
focus 현재 포커스가 있는 form
input 모든 입력 폼
selected option 중 선택된 요소
hidden
visible
감춰진 요소
보이는 요소
header h1~h6 element

-  위치기반 필터 선택자

선택자 선택 요소
:first 첫번째 요소
:last 마지막 요소
:first-child
:last-child
첫번째 자식
마지막 자식
only-child 형제가 없는 요소
even
odd
짝수번째 요소
홀수번째 요소

-  함수기반 필터 선택자

선택자 선택 요소
:not(filter) 해당 선택자가 아닌 모든 요소
:contains(str) 해당 텍스트를 포함하는 요소
:nth-child(n) n번째 자식(들)
:eq(n)
:gt(n)
:lt(n)
n번째 요소
n번 초과 요소들
n번 미만 요소들
:has(f) 해당 선택자와 하나 이상 일치하는 요소들

 

-  래퍼세트

-  JQuery는 선택자를 통해 찾은 DOM 객체들을, 래퍼세트에 담아 반환한다

-  래퍼세트는 다양한 메소드를 지원해 DOM 처리를 돕는다

 

-  요소 반복

-  $.each(array, function(index, item) { } );

-  array의 각 요소들마다 foreach를 돈다. index : 배열 인덱스, item : array의 각 객체들

 

-  $(selector).each( function(index, item) { } );

-  $(selector)의 결과가 array역할을 한다

 

-  filter() : 기존 래퍼세트에서 DOM요소를 추가로 거른 후 반환

-  내부에 선택자 / 함수가 온다

-  필터 선택자로도 불충분한 경우, 함수를 사용해 필터링 조건 명시

 

-  find() : 래퍼세트에 대해 find 선택자를 만족하는 모든 자손요소 반환

 

 

4. DOM 객체 제어

 

속성 제어 메소드

-  attr(name) name에 해당하는 속성 값을 반환

-  attr(name, value)는 해당 속성에 값을 설정

-  removeAttr(name) 해당 속성 제거

 

-  addClass(className) class 추가

-  removeClass(className) class 제거

-  toggleClass(className) 클래스가 있으면 제거, 없으면 추가

 

-  css(styleName) css값 조회

-  css(name, value) css 값 설정

 

-  html() html 반환 (태그 포함)

-  html(value) html 설정

 

-  text() text반환 (태그 제외)

-  text(value) text설정

 

-  DOM 객체 추가

-  $("<h2>hello world!</h2>").css(~~).appenndTo("body");

-  $() : DOM객체를 바로 생성

 

-  DOM 객체 삭제

-  $(selector).remove() 모든 요소를 삭제

-  $(selector).empty() 모든 요소, 하위 자식요소까지 삭제

 

-  DOM 객체 삽입

-  이미 존재하는 객체에 다른 객체 삽입

-  $(A).append(객체) A의 자식 맨 뒤에 객체 삽입

-  $(A).prepend(객체) A의 자식 맨 앞에 객체 삽입

-  $(A).after(객체) A의 형제 바로 앞에 객체 삽입

-  $(A).before(객체) A의 형제 바로 뒤에 객체 삽입

-  appendTo, prependTo, insertAfter, insertBefore : A와 B의 입장이 반대

-  $(B).appendTo(A);

 

 

5. JQuery Event

 

-  이벤트 핸들러를 할당,해제하는 메소드 제공

-  click함수로 클릭 처리 등

 

Event bind하기

-  bind(eventType, data, listener)

-  eventType : 핸들러를 할당할 이벤트 종류

-  data : 핸들러 함수에서 사용할 data

-  listener: 수행되는 핸들러 함수

 

-  unbind(eventType, handler)

-  bind된 핸들러 제거

 

-  on(eventType, listener)

-  동적 DOM 객체에도 적용 가능

-  기존 연결 방식은 동적 DOM 객체에는 적용되지 못한다

-  $().on("click", selector, function() { } );

-  selector에 해당하는 DOM 객체들도 이벤트 바인드 가능

 

-  off()

-  이벤트 등록 제거

 

Simple Event Bind

-  on함수 대신, eventType을 직접 사용할 수 있다

-  .on("click"~~)는

-  .click(~~)와 같다

 

MouseEvent

이벤트 발생조건
click 마우스로 클릭 시
dbclick 더블클릭
mousedown 버튼 누를 때
mouseup 버튼 뗄 때
mouseenter 커서가 들어올 때
mouseleave 커서가 나갈 때
mousemove 마우스가 움직일 때
mouseout 마우스가 벗어날 때
mouseover 마우스가 들어올 때

 

Keyboard Event

이벤트 발생조건
keydown 버튼 누를 때
keypress 글자 입력시
keyup 버튼 뗄 때

-  버튼 누름 -> 글자 입력됨 -> 버튼 떼짐 의 순서로 발생한다

 

Window Event

이벤트 발생조건
ready DOM 객체가 준비되면
load 윈도우를 호출시
unload 윈도우 닫을 때
resize 윈도우 크기 변화시
scroll 스크롤시
error 에러발생시

 

Input Event

이벤트 발생조건
change 입력 내용 변경시
focusin 포커스가 들어갈 때 (버블링)
focusout 포커스가 나갈 때 (버블링)
focus 포커스가 들어갈 때
blur 포커스가 나갈 때
select 입력 선택할 때
submit submit시
reset reset시

 

버블링이란?

-  div - ul - li 구조의 태그가 있다고 할 때, 버블링이 적용되어 있으면

-  li에서 발생한 이벤트에 대해 ul -> div의 핸들러도 처리를 한다

-  ex) li에 포커스 발생시, ul div의 포커스 핸들러도 처리하는 식

 

'WEB 공부' 카테고리의 다른 글

[WEB] Backend - EL, JSTL  (0) 2021.05.16
[WEB] Backend - Servlet, JSP  (0) 2021.05.16
[JAVA] JDBC  (0) 2021.05.16
[WEB] Frontend - Bootstrap  (0) 2021.05.15
[WEB] Frontend - AJAX  (0) 2021.05.15
[WEB] Frontend - JavaScript, WebBrowser  (0) 2021.05.08
[WEB] Frontend - HTML, CSS  (0) 2021.05.08

<한줄요약>

JavaScript : 웹 페이지의 동적 요소(추가, 삭제, 사용자 입력)을 처리하기 위하여

 

1. JS란?

 

-  브라우저는 JS를 HTML과 함께 다운로드, 실행

 브라우저의 JS엔진을 이용해 웹상에서 동작하는 프로그래밍 언어

 

 

2. HTML에서 JS 사용하기

 

 HTML에서는 <script type="text/javascript"> 태그로 JS를 선언한다. (최신버전 기준 type 생략 가능)

외부의 JS파일을 src속성으로 import할 수도 있으며, 직접 작성할 수도 있다.

head, body어디에 있어도 상관 없지만, head에 둘 경우 body 출력 전 점검사항이 늘어나 느려질 수 있다.

 

 

3. JS 문법

 

주석 : Java와 동일, //와 /* */

변수 : type이 없다, var로 선언, 값이 할당되는 중 자동으로 type이 결정된다.

 

기본 자료형

자료형 설명
숫자형, number 정수/실수
문자열, string 문자, 문자열
boolean true/false
undefined 초기화되지 않음
null 값이 존재하지 않음

숫자를 정수/실수로 구분하지 않는다

소숫점 연산시 기본적으로 오차가 발생

기본 연산자 : 자바와 같다. + - * / %

-  Infinity : 무한대. 0으로 나누는 행동을 했을때 발생

NaN : 계산 결과가 숫자가 아닐때 발생

 

문자열과 문자를 구분하지 않는다

'' "" 둘다 사용 가능. \를 사용한 특수문자도 지원

 

boolean은 true/false중 하나를 가진다

-  null, undefined, 빈 문자열, 숫자0은 false와 같다

 

undefined : 시스템 레벨에서 할당되지 않은 변수

null : 코드의 결과값이 없음

 

자동 형 변환

자료형이 다른 변수들끼리 연산해도 자동으로 변환되어 적용된다.

string + int : int가 string으로 변환

-  '1'+23 = '123'

 

변수 호이스팅

- 호이스팅 : 모든 선언을 해당 Scope의 처음에 처리하고 본문을 진행한다

var a = 123; 의 경우,

var a가 먼저 선언되고, 진행 중 var a=123;의 위치에 도달했을때 123으로 초기화된다.

그 이전에 참조할경우 undefined로 참조된다.

 

let과 const

상수는 const로 선언 ( ex. const LIST_SIZE=10; )

var는 기본적으로 전역 Scope

let, const는 해당 block을 Scope로 가진다

let, const는 호이스팅시 undefined로 초기화되지 않아 참조할 수 없다

let은 var와 달리 동일 Scope에서 재선언 불가

 

비교연산자

== : value가 동일한지 확인, '1'==1 은 true이다

=== : type까지 동일한지 확인 '1'==='1'은 false이다 (string과 number로 다름)

 

조건문

if(조건식) else if(조건식) else 자바와 같다

switch-case 자바와 같다

 

반복문

while(조건식). 자바와 같다

do/while 최초 1회는 반드시 수행. 자바와 같다

for( ; ; ) 자바와 같다

for(var key in list) 객체의 key에 대한 foreach로 동작.

-  for(var value in list) 객체의 value에 대한 foreach로 동작. ES6 추가문법, iterator 속성 필요

-  array.foreach( function(item) {} ) array의 각 원소에 대해 foreach로 동작. ES6에선 set/map 지원

 

 

4. 객체

 

이름(key)과 값(value)으로 구성된 property들의 집합

기본 자료형을 제외한 나머지 모든 값들은 객체이다.

-  JS에서는 함수 또한 객체로 취급한다

 

객체 생성

 

1. 객체 리터럴

var player = {
	name : "player1",
	level : 50,
	class : "warrior",
	info : function(){
		console.log(name+ "의 레벨은 " +level +"이며 직업은 " + class+ "입니다.");
	},
};

 

직접 {}안에 각 property들을 명시하여 생성

 

2. Object 생성자 함수

var player = new Object();

player.name = "player1";
player.level = 50;
player.class = "warrior";
player.info = function(){
    console.log(name+ "의 레벨은 " +level +"이며 직업은 " + class+ "입니다.");
};

-  Object로 생성 후 property를 할당

 

-  3. 생성자 함수

function Player (name, level, class){
	this.name = name;
    this.level = level;
    this.class = class;
    this.info = function(){
    	console.log(name+ "의 레벨은 " +level +"이며 직업은 " + class+ "입니다.");
    };
}

var player1 = new Player("player1", 50, "warrior");
var player2 = new Player("player2", 30, "mage");

-  생성자 함수를 만든 후 활용. 중복코드 감소

 

객체 속성 조회, 변경, 추가, 제거

 

-  1. 객체.속성명으로 접근

-  2. 객체["속성명"]으로 접근

-  속성명에 특수문자, 공백, 연산자 등이 있다면 2번방법으로 조회

 

-  접근한 속성에 값을 할당하면 속성의 값이 새로운 값으로 변경된다

-  ex. player1.level = 10;

-  ex2. player1["level"]=10;

 

-  값을 할당한 속성이 없다면 신규 property로 추가된다

-  ex. player1.money= 5000;

 

-  delete연산자로 속성 제거 가능

-  ex. delete player1.money;

 

 

5. 함수

 

-  JS에서 함수는 first-class 객체이다

-  함수는 변수, 배열, 객체등에 저장될 수 있고, 인자로도 전달되고, return값으로도 사용 가능하다

 

함수의 선언

 

-  1. 함수 선언문

function 함수명 (arg1, arg2 ...) {
	//내용
}

 

-  2. 함수 표현식

var 함수명 = function (arg1, arg2 ...) {
	//내용
}

 

-  3. 생성자 함수 이용

var 함수명 = new Function ("arg1", "arg2" .... "함수 내용");

 

 

함수 호이스팅

 

-  함수 선언문 : 호이스팅된다. 어디서든 호출 가능

-  함수 표현식 : 호이스팅되는건 var 변수. 초기화되기까진 undefined로 함수로 사용할 수 없다.

 

함수의 인자

 

-  인자의 갯수가 선언과 일치하지 않더라도 호출 가능하다

 

콜백함수

 

-  특정 이벤트 발생에 따라 자동으로 호출되는 함수

-  ex) 버튼 클릭시 특정 JS 함수가 작동하게 한다

-  주로 비동기식 처리를 위해 사용한다

 

 

6. Window 객체

 

-  웹 브라우저의 JS 최상위 객체

-  브라우저의 여러 객체, 속성이 존재한다

 

Window 객체 활용

-  alert() : 내부 문자열을 담아 경고창 호출

-  comfirm() : 내부 문자열을 담아 확인/취소창 호출

-  prompt() : 문자열을 입력할수 있는 창 호출

 

-  navigator는 브라우저의 정보를 담고있다. chrome인지, ie인지, firefox인지 구분 가능

 

-  location.href=url  : url로 이동한다

-  history.back()/forward() : 뒤로가기, 앞으로가기

 

-  window.open('url', 'name', 'attr', history) : 새 창을 연다

-  이 url에, 이 name으로, 이 attr특성으로, history 덮어쓰기 여부 등 조절 가능

 

-  window.close() 닫는다

-  window.opener() 이 창을 연 창, 즉 부모 창을 컨트롤할 수 있게 해준다.

 

 

7. DOM (Document Object Model)

 

-  문서의 요소들을 tree 계층구조로 표현

-  최상위 노드는 window객체의 document 객체가 위치한다.

-  문서 요소의 추가, 수정, 삭제 지원

 

신규 객체 생성하기

 

-  element를 만들고, text를 넣고, document에 넣는다

var h2 = document.createElement("h2");
var msg = document.createTextNode("hello world!");

h2.appendChild(msg);
document.body.appendChild(h2);

 

-  객체에 속성 추가/조회는 get/setAttribute함수로 할 수 있다.

var img = document.createElement("img");
img.setAttribute("src","img.jpg");
img.setAttribute("width", 160);
img.setAttribute("height", 250);

document.body.appendChild(img);

 

-  객체 하위에 HTML 추가는 innerHTML로 가능하다

-  객체 하위에 text 추가는 innerText로 가능하다

var div = document.createElement('div');
var div2 = document.createElement('div');

div.innerHTML = '<h1>hello world!!</h1>';
div.innerText = 'hello world!!';

 

문서에서 객체 찾기

 

-  id로 찾기 : getElementById(id) : element 한개 반환

-  class로 찾기 : getElementsByClassName(className) : element의 배열을 반환

-  tag으로 찾기 : getElementsByTagName(tagName) : 배열반환

-  name으로 찾기 : getElementsByName(name) : 배열반환

-  css의 선택자 사용

-  querySelector(selector) : 선택자에 맞는 element중 첫번째 하나

-  querySelectorAll(selector) : 선택자에 맞는 element 전부

 

문서에서 객체 제거

 

-  removeChild(node);

 

 

8. 이벤트 (Event)

 

-  웹 페이지에서 발생하는 여러 상호작용들을 event라 한다

-  마우스 클릭, 키보드 입력, 드래그 등등

-  일반적으로 이벤트-함수가 연결되고, 이벤트 발생시에 호출한다.

-  이벤트 발생시 호출될 함수, 이벤트 핸들러를 만들어 연결해줘야 한다.

 

이벤트 종류

 

-  마우스

-  onclick : 마우스로 클릭시 발생

-  ondblclick : 더블클릭

-  onmousedown : 마우스 버튼이 눌렸을 때

-  onmouseup : 마우스 버튼이 올라갈 때

-  onmouseover : 커서가 들어올 때

-  onmouseout : 커서가 나갈 때

-  onmousemove : 마우스가 움직일 때

 

-  키보드

-  onkeypress : 키보드가 눌렸을 때

-  onkeydown : 키보드를 누르는 순간

-  onkeyup : 눌린 키가 올라오는 순간

 

-  frame

-  onload : 모든 로딩이 끝났을때

 

-  form

-  onsubmit : 전송될 때

-  onreset : reset될 때

-  onfocus : 입력 포커스가 들어올 때

-  onblur : 포커스가 나갈 때

 

이벤트 핸들러 등록

 

-  1. 인라인 이벤트 핸들러

<div onclick="javascript:alert('hello world!');">클릭
// 2가지 함수 호출
<div onclick="func1(); func2();">클릭

-  클릭시 js가 호출되 hello world! 메시지의 alert 창이 뜬다

 

-  2. 이벤트 핸들러 property

-  JS상에서 DOM을 찾아 선택하고 이벤트 핸들러를 등록한다

<script>
document.getElementById("id").onclick = function () {
	alert("hello world!");
};
</script>

-  하나의 DOM에 2개의 핸들러를 등록할 수 없다.

 

-  3. addEventListener방식

-  이벤트 이름, 핸들러를 전달하면 등록해준다

<script>
document.getElementById("id").addEventListener("click", openAlert, false);

function event(){
	alert("hello world!");
};
</script>

-  하나의 이벤트에 하나 이상의 핸들러 추가 가능

 

 

9. 브라우저 저장소

 

-  사용자 로컬에 데이터를 보관한다.

-  JS로 조작 가능

-  Cookie와의 차이 : 유효기간이 없으며, 가용 용량이 더 크다

-  key - value pair로 저장된다.

 

-  localStorage에 데이터 저장하기

<script>
	function storage(){
    	localStorage.Data = "testData";
    	localStorage["Data"] = "testData";
    	localStorage.setItem("Data", "testData");
    };
</script>

 

-  localStorage의 데이터 획득하기

<script>
	function storage(){
    	var val = localStorage.Data;
    	var val = localStorage["Data"];
    	var val = localStorage.getItem("Data");
    };
</script>

 

-  localStorage의 데이터 삭제하기

<script>
	function storage(){
    	localStorage.removeItem("Data");
        //전체삭제
        localStorage.clear();
    };
</script>

 

'WEB 공부' 카테고리의 다른 글

[WEB] Backend - EL, JSTL  (0) 2021.05.16
[WEB] Backend - Servlet, JSP  (0) 2021.05.16
[JAVA] JDBC  (0) 2021.05.16
[WEB] Frontend - Bootstrap  (0) 2021.05.15
[WEB] Frontend - AJAX  (0) 2021.05.15
[WEB] Frontend - JQuery  (0) 2021.05.09
[WEB] Frontend - HTML, CSS  (0) 2021.05.08

<한줄요약>

HTML : 웹 문서 구조를 표현하기 위한 언어

CSS : HTML로 짜여진 구조를 어떻게 화면에 띄울지 결정

 

1. HTML

 

-  hypertext markup language

-  웹을 표현하는 문서 양식

-  tag를 사용해 문서 표현

-  시작태그 <tag> 와 종료태그 </tag> 사이에 내용을 정의

-  각 tag별 의미가 있으며, 이에 해당하는 내용을 화면에 표시한다

 

Web의 작동 원리

-  client가 서버에 요청

-  서버는 요청을 분석 후 결과를 HTML로 전송

-  client는 받은 HTML을 브라우저에 표시

 

웹 브라우저 : tag를 해석하여 이를 화면에 표시

 

 

2. CSS

 

-  HTML문서가 화면에 나타나는 양식을 정의

-  동일한 HTML 구조에 다른 CSS를 적용 가능

 

-  CSS 규칙 - 선택자 / 선언 2 part

-  선택자 : style이 어디에 적용될 것인지

-  선언 : 어떤 style이 적용될 것인지

-  선언은 속성:값; 의 형식으로 이루어진다.

-  속성 : 바꾸고 싶은 요소

-  값 : 바뀔 value

ex) .img { display:none; } = img class를 표시하지 않겠다

-  여러 선택자에 같은 style 적용 : 선택자를 , 로 나열한다

 

 

3. HTML문서에 CSS 적용 방법

 

외부 스타일 시트

 <link rel="stylesheet" type="text/css" href="css파일경로">

 @import url("css파일경로");

 등 외부의 css 파일을 호출

 장점 : 여러 페이지에 동일한 스타일 쉽게 적용. 한번 수정하면 전체 다 변경 가능

 

내부 스타일 시트

 <style> 태그를 이용해 페이지 내부에 css 규칙을 작성

 <style>은 <head>안에 위치한다.

 단점 : 여러 페이지에 중복적용해야하면 ctrl c+v해야

 

inline 스타일 시트

 각 tage 내부의 style attribute에 css를 적용

 style의 값은 css규칙

 가장 적용 우선순위가 높은 방법

 

 

4. HTML 개요

 

모든 tag에 있는 global attribute

 

 class="classname" : 클래스 이름을 지정. 여러 클래스 지정 가능. 다른 tag의 class값과 중복 가능

 id="idname" : ID를 지정. 다른 tag의 id와 중복 불가(에러는 나지 않는다)

 style="" : css지정

 title="" : title 지정. 마우스 갖다댔을때 나오는 텍스트

 dir="" : 텍스트 방향 지정. 기본적으로 ltr(left to right)

 

주석

 <!-- 주석내용 -->

 

html문서의 전체 구성

 html, head, body

 

<html> : HTML문서임을 정의한다. head와 body로 구성

 

<head> : HTML문서의 사전 처리 부분, 대부분 화면에 나타나지 않는다

-  <title> : 브라우저 탭의 이름(이건 화면에 나타난다)

 <meta> : 메타데이타 (문서 작성자, 일자, 인코딩 정보 등등)

 <style> : 내부 스타일 시트

 <linke> : 외부 파일 참고

등을 기술한다

 

<body> : HTML문서의 본문. 브라우저에 표시되는 부분

id속성을 이용해 tag의 식별 가능

-  class속성을 이용해 CSS 부여

-  <h1~6> 속성으로 글자의 크기 지정

-  <section> 태그로 문서의 영역을 구분. <h1>의 크기도 상대적으로 작아진다

 

HTML에서 특수문자 입력하기

-  <, >, &등의 문자는 HTML에서 의미를 가지는 문자들로, 단순히 사용할 수 없다

표현하고자 하는 문자 표기법
(공백) &nbsp;
< &lt;
> &gt;
& &amp;
" &quot;

 다음과 같이 변경해 표현

 

 

5. HTML 마크업 요소

 

텍스트 포맷 관련

 <b> 굵은 글씨로표시

 <strong> 굵은 글씨 + 중요한 부분을 알림

 <i> 이탤릭

 <s> 취소선

 <u> 밑줄

 

목록(list) 관련

<ul> 번호 없는 목록 (심볼)

<ol> 번호 있는 목록 (숫자, 알파벳, 로마숫자 등)

-  <li> ul/ol의 하위에 들어가는, 리스트 각 줄 태그

ol 속성

  1 : 숫자 (기본값)

   a, A : 알파벳 (소, 대문자)

   i, I : 로마숫자 (소, 대문자)

 

표(Table) 관련

-  thead, tbody, tfoot으로 행들을 구분

-  <tr> : 각 row를 나타낸다.

-  <td> : tr내부에서, 각 cell을 나타낸다.

-  <caption> : 테이블의 제목을 지정한다, 기본 : 가운데 정렬

 

-  <thead> : 머리글

-  <tbody> : 본문 내용

-  <tfoot> : 꼬리글

-  위의 태그들은 최소 하나 이상의 <tr>태그를 가져야 한다

 

열 단위의 접근

-  <colgroup> 열 그룹을 만든다

-  <col> 열 단위로 묶어 그룹을 만든다.

 

행/열 병합

-  <td>내부 속성으로 colspan="병합할 갯수", rowspan="병합할 갯수" 로 지정 가능

 

Image 관련

-  <img>태그로 삽입

-  src속성으로 이미지의 경로를 지정한다 - 상대경로/URL 다 가능

-  height/width속성으로 size지정

 

하이퍼링크

-  <a>태그를 사용

-  href 속성으로 클릭했을때 이동할 URL/문서 지정

-  target속성으로 현재 창 / 새창에서 열기 / 부모 창에서 열기 등 지정 (_self, _blank, _parent)

-  href="#idname" 으로 지정시, 해당 id의 태그 위치로 이동한다

 

-  <map>으로 이미지에 link 지정

-  <area>태그로 영역을 지정해서, 한 이미지라도 누르는 위치에 따라 다른 경로로 안내한다

-  <area>는 href / target / shape등의 속성을 지닌다.

-  shape로 rect, circle 등 모양을 지정 후 coords로 세부 사항 지정

 

-  <link> 태그로 외부 자원 연결 (위에서 본 css 등)

-  <head>내부에서 정의한다

-  rel속성 : 어떤 관계로 연결된 자원인지 (js, css 등)

 

프레임

-  현재 문서의 일부에 다른 문서를 띄운다

-  <iframe> 태그 사용

-  src : 띄울 문서의 경로

-  height, widht : 크기

 

Form 요소

-  client와 server간에 데이터를 주고받기 위한 용도

-  client는 form에 데이터 입력 후 서버로 전송한다

-  서버는 이에 따른 처리

 

데이터 입력

-  <form> form을 정의

-  <input> 데이터를 입력받기 위함

-  <textarea> 여러줄의 text 입력

-  <button> 버튼

select box

-  <select> selectbox

  -  <option> selectbox 내부의 각 값들 (위의 한국/일본/중국)

<label> 입력값에 라벨 달기, label을 클릭해도 input으로 포커스 지정

<fieldset> form 요소를 그룹으로 묶는다

-  <legend> 묶은 그룹에 제목 지정

 

전송 방식 결정

form의 속성값으로 정한다

method="GET / POST" (후술)

name : form의 이름을 지정

action : 이 form을 전송했을때 처리할 server 스크립트 지정

target : action에서 지정한 server 스크립트를 어디에서 열 것인가

 

 

input 종류

type에 따라 여러가지 형태로 나타난다

type 값 형태
text 텍스트 한 줄
password 비밀번호, text를 *처리
search 검색상자
tel 전화번호
url url (url 형식 체크)
email 메일주소 (email 형식 체크)
checkbox 2개 이상 선택 가능한 체크박스
radio 1개만 선택 가능한 체크박스
file 파일 첨부
number 숫자를 직접 입력
range 숫자를 입력하는 사이드-바
button 기능이 지정되지 않은 버튼
hidden 보이지 않음
(name, value등을 이용해 server로 데이터 전송)
submit 서버로 전송
image submit 버튼
그런데 이제 버튼에 이미지를 씌운
reset form 입력값 리셋

-  number / range의 속성 : min, max, step, value (최소값, 최대값, 값들 사이의 간격, 기본값)

-  checkbox / radio의 속성 : radio의 name속성 = 그 값들이 다 같아야한다

                                    checkbox는 name 관계없이 다중선택

-  button의 속성 : value = 버튼 안의 글자, onclick = 눌렀을때 일어날 동작

-  image의 속성 : src = 이미지 주소

-  file의 속성 : multiple = 여러 파일을 업로드 가능

 

공통속성

-  placeholder : 기본값. 회색글자로 표시. 클릭시 사라짐

-  readonly : 수정 불가

-  required : 필수입력항목

 

여러 data중 선택

-  <select> 태그 사용

-  내부의 <option> 태그로 각 항목을 지정한다

-  option 태그의 속성

  -  value : 각 항목의 값

  -  selected : 기본 선택값

optgroup 적용

-  <optgroup> 로 옵션들을 그룹화한다

 

여러 줄 입력

-  <textarea> 태그 사용

-  cols rows속성으로 박스의 크기 지정

 

기타 태그

-  <button>

-  <input type="button">과 거의 동일하다. submit, reset, button 3종류가 있는것도 동일

-  차이점 : CSS/img등으로 자유롭게 디자인 변경 가능

 

-  <progress>

-  작업의 진행률 게이지 바

-  value 속성으로 현재 진행중인 값, max 속성으로 완료(최대)값 설정

 

공간 분할 태그

-  <div>

-  block형식으로 공간 분할

 

-  <span>

-  inline형식으로 분할

 

 

6. CSS선택자

 

-  HTML문서에서 CSS의 적용 대상을 선택하기 위한 selector

 

일반 선택자

 

전체 선택자

-  * { }

-  모든 element를 선택한다

-  거의 사용하지 않는다

 

타입 선택자

-  typeName {}

-  div {} 으로 모든 div에 CSS를 적용한다

-  div, span {} 이렇게 2가지 이상의 타입에 적용

 

클래스 선택자

-  .className {}

-  .target {} 으로 class="target"이 있는 모든 element에 적용

-  div.target {} 으로 class="target"이 있는 div들에 적용

 

ID 선택자

-  #IDName {}

-  #target {} 으로 id="target"인 element에 적용

-  id는 1개이므로, 다른 조건 제한 옵션은 필요 없다

 

선택자의 우선순위

-  전체 < 타입 < 클래스 < ID

 

복합 선택자

 

하위 선택자

-  element element {}

-  div p {} 로 div에 포함되는 모든 p 태그에 적용

-  div와 p 사이에 몇개의 다른 태그가 있어도 적용된다 (n단계 하위 요소까지 다 적용)

 

자식 선택자

-  element > element {}

-  div>p {} 로 div의 모든 자식 p 태그에 적용

-  div와 p 사이에 다른 태그가 존재하면 적용되지 않는다

 

인접 형제 선택자

-  element + element {}

-  div + p {} 로 div 이후 계층이 같은(형제) p 태그중 첫번째에 적용

-  여러 형제 element들 중 첫번째만 선택

 

일반 형제 선택자

-  element ~ element {}

-  div ~ p {} 로 div 이후 계층이 같은 p 전체에 적용

 

가상 클래스 선택자

 가상의 클래스를 선택한다

 element:selector 형식으로 사용

   ex) a:link {}

가상 클래스 선택자 선택 대상
:link 방문하지 않은 링크
:visited 방문했던 링크
:hover 마우스가 올라가있을때 적용
:active 활성화(클릭 등)된 경우 적용
:focus 포커스를 가질때
:first-child
:last-child
첫번째
마지막
자식을 지정
:nth-child(n) n번째 자식(들)을 지정
(2n+1)과 같은 식으로 수열로 지정 가능
n은 0부터 시작 자식의 번호는 1부터 시작

 

가상 엘리먼트 선택자

 가상의 엘리먼트 선택한다

 element::selector 형식으로 사용

   ex) p::selection {}

가상 클래스 선택자 선택 대상
::after 지정 요소 뒤에 content 추가
::before 지정 요소 앞에 content 추가
::first-letter
::first-letter
지정 요소의 첫번째 문자
지정 요소의 첫번째 줄
::selection 사용자가 선택하는 요소들
(ex. 마우스를 드래그하면 적용)

 

속성 선택자

 특정 속성 / 속성값을 가지는 element를 선택

 [속성A = 값B] A속성의 값이 B인 element를 선택한다

속성 선택자 선택 대상
[A] A 속성이 포함된 element
[A=V] A속성의 값이 정확히 V인 element
[A~=V] A속성의 값이 V 단어를 포함하는 element
(단어란 : 앞/뒤가 공백문자로 분리된 것)
[A^=V] A속성의 값이 V로 시작하는 element
[A*=V] A속성의 값이 V를 포함하는 element
(단어가 아님)
[A$=V] A속성 값이 V로 끝나는 element
[A|=V] A속성값이 정확히 V이거나,
V-으로 시작하는 element

 

선택자들의 우선순위

-  동일한 element에 여러 선택자가 적용될 경우,

1. css문서 상 더 아래에 기술된 선택자

2. 더 구체적인 선택자

3. !important를 가지는 선택자

가 우선 적용된다

 

 

7. CSS 태그별 세부 속성

 

Font 속성

font-family : 글꼴, 이름에 공백이 있을경우 ""으로 감싸준다,

                    여러개 입력시 앞에서부터 확인, 설치되지 않은 폰트면 넘어간다

-  font-size : 글자 크기, px, pt, 150%등으로 표현

font-style : 글자 스타일, 이탤릭 등

font-weight : 글자굵기, bold, bolder 등

font : font 속성 일괄설정

 

Text 속성

text-align : text 정렬 방식 지정, left, right, center, justify

text-ident : 첫 line 들여쓰기 지정

text-transform : 대/소문자화, uppercase, lowercase 등

vertical-align : 수직 정렬

-  color : 색 지정

line-height : 줄간격 지정, pt, px, %등으로 표현

 

디자인 속성

-  cursor : 마우스 모양 변경

display : 표현 방식 조정, inline, block, none

background-color : 배경색, color값 혹은 transparent 지정

background-image : 배경이미지, url

background-repeat : 배경 이미지 끝나면 반복 여부

background-position : 배경 이미지 위치 지정

background : 배경 속성 일괄설정

 

Table 속성

-  width, height : 너비, 높이

-  text-align : 내부 정렬(수평)

-  vertical-align : 내부 정렬(수직)

-  border-width : 외곽 너비

-  border-style : 외곽 스타일

-  border-color : 외곽 색, 4방향 각각 다른 색 가능

-  border : 외곽 속성 일괄설정, 4방향 다른 색 불가능

 

박스모델 속성

-  CSS는 모든 element를 어떠한 상자에 들어있는 상태로 생각한다

-  박스안에서 element의 위치, 박스와 박스의 간격 등을 조정 가능

-  margin : Box의 외곽거리를 지정, 4방향 지정 가능, 속성값 auto로 상/하 좌/우 균등 분배 가능

-  padding : element와 Box의 간격을 조정, 4방향 지정 가능

-  min-height : 최소 높이를 보장, 브라우저 크기가 작아져도 최소치를 유지

 

포지션 관련 속성

-  width, height : 높이, 너비. auto로 설정시 가능한 크기만큼 채운다

-  position : static (top/left로부터의 거리), absolute (상위 box 기준 top,left,right,bottom 등 위치 지정)

-  overflow : 상위 element보다 지금 element가 클 경우 처리법. visible, hidden, auto

-  visiblility : 화면에 보일지 말지를 결정. display:none과는 달리 표시하지 않아도 영역은 차지한다

-  z-index : 여러 element를 겹쳐 표시. z-index값이 큰쪽이 위로 온다.

 

 

8. semantic tag

 

semantic tag란?

-  <h1>태그와 <font size="xx"> 는 그 의미가 동일하다

-  하지만 font태그는 아무 의미도 없지만, h1태그는 header, 그중 최상위 태그라는 의미를 내포

-  자기 자신이 나타내는 바를 알림으로서, 어떠한 의미를 가지게 한다

-  콘텐츠의 의미를 내포하는 이러한 태그를 semantic tag라 한다.

 

-  form, table, img 등도 각각 나타내는 바가 명확한 semantic tag이다.

-  header : 보통 nav, search form등이 들어가는 머리 부분으로 사용하는 태그

-  nav : 다른 문서/사이트로 연결하는 링크가 모여있는 태그

-  section : 같은 주제를 가지는 element의 묶음

-  aside : 왼쪽/오른쪽의 사이드 내용

-  footer : 웹사이트정보, 연락, copyright 등을 표현

 

'WEB 공부' 카테고리의 다른 글

[WEB] Backend - EL, JSTL  (0) 2021.05.16
[WEB] Backend - Servlet, JSP  (0) 2021.05.16
[JAVA] JDBC  (0) 2021.05.16
[WEB] Frontend - Bootstrap  (0) 2021.05.15
[WEB] Frontend - AJAX  (0) 2021.05.15
[WEB] Frontend - JQuery  (0) 2021.05.09
[WEB] Frontend - JavaScript, WebBrowser  (0) 2021.05.08

2021.05.01 - [기타] - [WEB] Selenium으로 트위터 자동 로그인하기 (JAVA)

 

[WEB] Selenium으로 트위터 자동 로그인하기 (JAVA)

driver.get("https://twitter.com/"); //id wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@id=\"react-root\"]/div/div/div/main/div/div/div/div[1]/div[1]/div/form/div/div[3]/div")));..

nato-blog.tistory.com

  위 글에 써진 대로 트위터 / 그랑블루의 쿠키를 취득, 한번 로그인한 정보를 유지하도록 만들었다

 

0. 기획 변경

 

  처음에는 그랑블루 계정들을 다 흝으며 소환석 데이터를 얻어 볼 생각이었지만, 힘들겠다는 생각이 들었다.

 

  우선, 소환석은 이벤트 등으로 신규 소환석을 얻음에 따라 자주 변경되는 데이터이다. 데이터를 얻는건 어렵지 않지만, 바뀌는 데이터를 추적하는건 다른 문제이다.

 

  또한 현재 신규계정번호가 3000만을 넘었으며, 작년 했던 켐페인이 "유저수 2700만 기념 켐페인!" 이었단걸 생각하면 현재 유저수는 못해도 2800만에 근접하지 않았을까 싶었다.

  이 경우 1초에 1명씩 확인한다 하면 하루 14만명 확인이 가능하며, 총 200일은 돌려야 전체 유저를 확인하게 된다.

  그정도면 내가 친구를 납치해다 만두만 먹이며 그랑블루를 시키는 쪽이 더 빠르겠다 싶었다.

 

  그래서 특정랭크 이상의 유저만 관리하고, 일정 주기마다 데이터 갱신을 돌리는 식으로 하려고 생각해봤지만, (ex. 225랭크 이상인 유저가 40만이라면, 3~4일정도면 갱신 가능하다) 이 역시 처음 한번 분류하는게 힘들고, 랭크의 상승을 알기 힘들다는게 문제가 되었다.

 

  하여 기획을 변경해 게시판처럼 사람들이 자기 소환석 현황을 게시하고, 다른 사람들이 이를 확인할 수 있도록 하는 정도는 쉽게 만들수 있지 않을까 생각했다.

  기존 SNS/커뮤니티에 존재하던 친구찾기 게시글들을 한 장소에 모아놓는 느낌?

 

  여기서 게시판을 따로 사이트를 만들지 말고, 트위터에 게시글을 올리는 식으로 하면 좋겠다고 생각했다.

  트위터라면 누구나 쉽게 이용 가능하고, 검색 시스템같은것도 잘 지원해 조건 설정도 가능하니 말이다.

 

1. 플레이어 데이터 획득

 

  로그인 세션을 문제없이 취득했다면, 사용자 id만 있다면 누구든지 접근해서 데이터를 얻어낼 수 있다.

 

  그러므로 우선 어떤 데이터들을 획득할 지 정리해 클래스로 만들어 보았다.

  우선 입력된 id, 이름, 랭크(레벨)과 원 목적이던 14개의 소환석 정보를 획득토록 하였다.

  summon은 img태그에 저장된 이미지 주소를 저장하며, summonLevel은 text로 된 상세설명을 저장한다.

 

  데이터 추출은 간단하게, 해당 주소에 접속 후 html 태그를 찾아 내부 요소를 추출하는 식으로 간단하게 완료하였다.

 

  데이터 정상 추출을 확인하기 위해 이름, rank, 이미지를 표시할 뿐인 간단한 페이지를 만들었다.

 

 

  정상적으로 데이터를 띄우는 걸 볼 수 있다.

 

2. 이미지 추출, 합성

 

  저장한 이미지 url들은 ImageIO를 사용해 실제 image객체로 저장한 후, Graphics를 사용해 하나의 이미지로 합쳐주었다.

 

  배경이 될 이미지를 추출하고, png를 jpg로 변환한 후 graphics를 만든다.

 

  그리고 소환석들의 url으로 이미지를 추출해, size를 조정한 후 graphics로 그리도록 하였다.

 

 

  파일의 저장 경로는 해당 사용자의 id로 폴더를 만들어 저장하도록 했다.

 

 

  결과로 나온 이미지로, 엉망진창이지만.. 일단 의도한대로 작동한다는 점에 만족하고 다음 작업으로 넘어가기로 했다.

에러도 나지 않고, getAttribute("class") 등으로 테스트해봐도 class 값이 정상적으로 반환되는데, getText()만 내부 문자열을 반환하지 못할때

 

getAttribute("innerHTML") 이나 getAttribute("innerText") 으로 시도하면 정상적으로 반환받을 수 있다.

[문제링크]

 

20040번: 사이클 게임

사이클 게임은 두 명의 플레이어가 차례대로 돌아가며 진행하는 게임으로, 선 플레이어가 홀수 번째 차례를, 후 플레이어가 짝수 번째 차례를 진행한다. 게임 시작 시 0 부터 n − 1 까지 고유한

www.acmicpc.net

 

0. disjoint set 문제

 

1. A에서 B로 선분을 그으려 할 때, 이미 A와 B가 같은 집합에 속한다면 사이클이 생성된다

 

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main{
	public static void main(String[] args)throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		int n = pint(st.nextToken());
		int m = pint(st.nextToken());
		
		init(n);
		
		for (int i = 0; i < m; i++) {
			st = new StringTokenizer(br.readLine(), " ");
			int x = pint(st.nextToken());
			int y = pint(st.nextToken());
			if(!union(x,y)) {
				System.out.println(i+1);
				break;
			}
			else if(i==m-1) {
				System.out.println(0);
			}
		}
		
	}
	static int[] parents;
	
	static void init(int n) {
		parents=new int[n];
		for (int i = 0; i < n; i++) {
			parents[i]=i;
		}
	}
	
	static int find(int n) {
		if(parents[n]!=n)return parents[n]=find(parents[n]);
		return n;
	}
	
	static boolean union(int x, int y) {
		int px=find(x), py=find(y);
		if(px==py)return false;
		
		parents[px]=py;
		return true;
	}
	
	static int pint(String s) {
		return Integer.parseInt(s);
	}
}

결과 화면

'알고리즘 문제 풀이 > BOJ 골드' 카테고리의 다른 글

[백준] 16724 - 피리 부는 사나이  (0) 2021.05.16
[백준] 1068 - 트리  (0) 2021.05.14
[백준] 16946 - 벽 부수고 이동하기 4  (0) 2021.05.13
[백준] 1062 - 가르침  (0) 2021.05.05
[백준] 17404 - RGB거리 2  (0) 2021.05.02
[백준] 10775 - 공항  (0) 2021.05.01
[백준] 1939 - 중량제한  (0) 2021.05.01

+ Recent posts