Java Script 기초

사전작업

  • 살행할 폴더 우클릭 : git bash here

  • VSCord 작동 : code .

  • 폴더, 파일 생성

  • PROJECT 아래에 생성

    • 폴더 생성 : step03_js_basic
    • 파일 생성 : index.html
    • 파일 생성 : main.js

JavaScript 작성

  • index.html 에 다음 내용 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html lang="ko">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width">
<title>Document</title>
<script src="./main.js"></script>
</head>

<body>
<h1>자바스크립트 연습</h1>
</body>

</html>
  • main.js에 다음 내용 작성
1
2
// hello world
console.log("hello!")
  • step03_js_basic 폴더에서 index.html을 오픈
  • 다음과 같이 페이지가 출력된다.

Untitled

시스템 로그

  • main.js 에 다음 내용 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// hello world
console.log("Hello!!!");

// 변수명 작성 스타일
// camel Case : numOne

const myName = "kmk";
const email = "abc@gmail.com";
const hello = '안녕 ${myName}!';

// print()
console.log(myName);
console.log(email);
console.log(hello);
  • html 페이지에서 우클릭 → 검사
  • 다음과 같이 시스템 로그가 출력되었다.

Untitled

key-value

  • key-value를 비롯한 여러 변수를 호출해본다.
  • main.js 에 다음 내용 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// hello world
console.log("Hello!!!");

// 변수명 작성 스타일
// camel Case : numOne

const myName = "kmk";
const email = "abc@gmail.com";
const hello = '안녕 ${myName}!';

// print()
console.log(myName);
console.log(email);
console.log(hello);

// 숫자
const number = 123;
console.log(number)

// Boolean
let checked = true;
let isShow = false;
console.log(checked)
console.log(isShow)

//undefied
let abc;
console.log(abc);

//null
let name = null;
console.log(name);

//재할당
name = 'kmk';
console.log(name);

// 파이썬 딕셔너리와 비슷
// key-value
const user = {
name: 'kmk',
age: 20,
isValid: true
}

console.log(user.name);
console.log(user.age);
console.log(user.isValid);
// console.log(user.user.city); undefined
  • 다음과 같이 시스템 로그가 출력된다.

Untitled

사칙 연산

  • main.js 에 다음 내용 추가
1
2
3
4
5
6
7
// 사칙 연산
const a=2;
const b=5;
console.log(a + b);
console.log(a - b);
console.log(a * b);
console.log(a / b);
  • 연산 결과가 시스템 로그에 출력된다.

Untitled

함수 선언과 호출

  • main.js 에 다음 내용 추가
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 함수의 선언과 호출
function helloFunc() {
console.log(1234);
}

helloFunc();

function returnFunc() {
return 123;
}

const fun_result = returnFunc();
console.log(fun_result);

function sum(a, b){
return a + b;
}

const sum_a = sum(1, 2);
console.log(sum_a);

const sum_b = sum(4,5)
console.log(sum_b);

// anonymous(익명 함수)
const world = function(){
console.log("We are the world");
}
world();
  • 결과가 시스템 로그에 출력된다.

Untitled

조건문

  • main.js 에 다음 내용 추가
1
2
3
4
5
6
7
// 조건문
const isDone = false;
if (isDone) {
console.log('done!')
} else {
console.log('Not Yet')
}
  • 결과가 시스템 로그에 출력된다.

Untitled

html & css

사전작업

  • 살행할 폴더 우클릭 : git bash here

  • VSCord 작동 : code .

  • 폴더, 파일 생성

  • PROJECT 아래에 생성

    • 폴더 생성 : step02_hello
    • 파일 생성 : index.html
    • 파일 생성 : main.css

CSS 작성

  • index.html 에 다음 내용 작성
1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=devie-width, initial-scale=1.0">
<title>돈까스집</title>
<link rel="stylesheet" href="./main.css" >
</head>
<body>
<div>Hello World</div>
</body>
</html>
  • main.css 에 다음 내용 작성
1
2
3
4
5
div {
width: 400px;
height: 200px;
background-color: blue;
}
  • step02_hello 폴더에서 index.html을 오픈
  • 다음과 같이 페이지가 출력된다.

Untitled

이미지 업로드

  • step02_hello 아래에 폴더 생성 : img
  • 사진을 img폴더 경로에 다운로드 : rainday
  • index.html 에 다음 내용 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=devie-width, initial-scale=1.0">
<title>돈까스집</title>
<link rel="stylesheet" href="./main.css" >
</head>
<body>
<div class = "weather_title">
<h1>오늘의 날씨</h1>
<p>오늘은 비가 많이 내릴 예정입니다. ~~</p>
<img src="./img/rainday.webp" alt="rain">
</div>
</body>
</html>
  • main.css 에 다음 내용 작성
1
2
3
4
5
6
7
8
9
10
11
div {
width: 200px;
height: 200px;
background-color: blue;
}

p{
color: navy;
text-indent : 30px;
text-transform: uppercase;
}
  • 지정한 이미지가 업로드되었다.

Untitled

div 클래스

  • div를 이용하여 글을 작성한다.
  • index.html 에 다음 내용 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=devie-width, initial-scale=1.0">
<title>돈까스집</title>
<link rel="stylesheet" href="./main.css" >
</head>
<body>
<div class = "weather_title">
<h1>오늘의 날씨</h1>
<p>오늘은 비가 많이 내릴 예정입니다. ~~</p>
</div>
<div class = "fruits">
<ul>
<li>사과</li>
<li>바나나</li>
<li>수박</li>
<li>오렌지</li>
</ul>
</div>
<div id="song">
<span>노래~~가사~~</span>
</div>
</body>
</html>
  • main.css 에 다음 내용 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
div {
width: 200px;
height: 200px;
background-color: blue;
}

div.fruits {
width: 500px;
height: 300px;
background-color: orange;
}

#song {
width: 500px;
height: 300px;
background-color: rgb(205, 235, 135);
}

p{
color: navy;
text-indent : 30px;
text-transform: uppercase;

}
  • 다음과 같이 차례로 출력된다.

Untitled

Label, Table

  • 라벨과 테이블을 사용해본다.
  • index.html 에 다음 내용 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=devie-width, initial-scale=1.0">
<title>돈까스집</title>
<link rel="stylesheet" href="./main.css" >
</head>
<body>
<div class = "weather_title">
<h1>오늘의 날씨</h1>
<p>오늘은 비가 많이 내릴 예정입니다. ~~</p>
</div>
<div class = "fruits">
<ul>
<li>사과</li>
<li>바나나</li>
<li>수박</li>
<li>오렌지</li>
</ul>
</div>
<div id="song">
<span>노래~~가사~~</span>
</div>

<br>
<input type = "text" value = "hello" />
<input type = "text" placeholder = "이름을 입력하세요"/>

<label>
<input type="checkbox" />사과
<input type="checkbox" checked/>바나나
</label>

<table>
<tr>
<th>항목명1</th>
<td>내용이 들어갑니다.</td>
</tr>
<tr>
<th>항목명2</th>
<td>내용이 들어갑니다.</td>
</tr>
<tr>
<th>항목명3</th>
<td>내용이 들어갑니다.</td>
</tr>
</table>

</body>
</html>
  • main.css 에 다음 내용 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
div {
width: 200px;
height: 200px;
background-color: blue;
}

div.fruits {
width: 500px;
height: 300px;
background-color: orange;
}

#song {
width: 500px;
height: 300px;
background-color: rgb(205, 235, 135);
}

p{
color: navy;
text-indent : 30px;
text-transform: uppercase;

}

input:focus {
background-color: blue;
}

Untitled

Ctrl + A 후 전체정렬

전체 정렬 : Ctrl + Alt + L

추가 공부

https://www.inflearn.com/course/html5

  • 해당 링크에서 필요한 강의를 찾아서 듣기
  • 최종적으로 홈페이지가 제작되는 강의나 책을 선택해야 한다.

참고 자료

html 기초

사전작업

  • 바탕 화면에 폴더 생성 : project
  • 폴더 우클릭 : git bash here
  • VSCord 작동 : code .

Untitled

  • 폴더, 파일 생성
  • PROJECT 아래에 생성
    • 폴더 생성 : step01_intro
    • 파일 생성 : index.html

html 작성

  • 코드 작성
1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=devie-width, initial-scale=1.0">
</head>
<body>
aaa
</body>
</html>
  • 저장 후 폴더에서 html파일 열기
  • 다음과 같이 작서한 내용이 출력되어 있다.

Untitled

링크 첨부

  • Naver 주소를 복사하여 다음과 같이 작성한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=devie-width, initial-scale=1.0">
<title>돈까스집</title>
</head>
<body>
<a href="https://www.naver.com/">NAVER</a>
<br>
<br>
<div>Hello World</div>
</body>
</html>

Untitled

이미지 추가

  • project/step01_intro 경로에 폴더 생성 : img
  • 아무 사진이나 다운받아서 폴더에 넣는다.
    • 사진을 다른 이름으로 저장 : temp
  • 여기까지 설정하고 다음과 같이 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=devie-width, initial-scale=1.0">
<title>돈까스집</title>
</head>
<body>
<a href="https://www.naver.com/">NAVER</a>
<br>
<br>
<div>Hello World</div>
<br>
<img src="./img/temp.jpg" alt = "ball">
</body>
</html>

Untitled

이미지 주소로 추가

  • 이미지 우클릭 : 이미지 링크 복사
  • 다음과 같이 링크를 붙여넣고 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=devie-width, initial-scale=1.0">
<title>돈까스집</title>
</head>
<body>
<a href="https://www.naver.com/">NAVER</a>
<br>
<br>
<div>Hello World</div>
<br>
<img src="./img/temp.jpg" alt = "ball">
<img src="https://img.animalplanet.co.kr/news/2020/01/07/700/tbg4j63622z4545z51af.jpg" alt = "fox">
</body>
</html>

Untitled

페이지 이동

  • 링크로 페이지 이동하기
  • 우선 step01_intro 아래에 폴더 생성 : about
    • about 아래에 파일 생성 : index.html
  • about/index.html에 다음 내용 작성
1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=devie-width, initial-scale=1.0">
<title>About</title>
</head>
<body>
<a href="../">Home</a>
About 페이지입니다.
</body>
</html>
  • index.html에 about/index.html 경로 추가
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=devie-width, initial-scale=1.0">
<title>돈까스집</title>
</head>
<body>
<! -- 키워드: 상대경로, 절대경로 -->
<a href="https://www.naver.com/">NAVER</a>
<a href="./about/index.html">About</a>

<br>
<br>
<div>Hello World</div>
<br>
<img src="./img/temp.jpg" alt = "ball">
<img src="https://img.animalplanet.co.kr/news/2020/01/07/700/tbg4j63622z4545z51af.jpg" alt = "fox">
</body>
</html>

Untitled

  • 다음 설정으로 코드 가독성을 높일 수 있다.
    • VSCord → 메뉴바 → 보기 → 자동 줄 바꿈

FrontEnd 세팅

웹개발을 위한 VS Code 기본 세팅 (notion.site)

  • VSCord → extention 에서 필요한 프로그램을 다운로드

Untitled

  • Korean 다운로드

→ restart

Untitled

  • beautify 다운로드

Untitled

  • ‘기능 기여도’ 탭

→ 명령 칸에서 다음 내용 복사

→ 복사 : HookyQR.beautify

Untitled

  • 검색 창 열기 : crl+ shift + p
  • 검색 : 바로가기 키

→ 기본 설정 : 바로 가기 키 열기

Untitled

  • 검색 : 앞서 복사했던 HookyQR.beautify 를 붙여 넣는다.
    • Beautify Selection을 클릭한다.

Untitled

  • 키 바인딩 조합 정의 : ctrl + alt + L

Untitled

  • live server 설치

Untitled

html

CSS

JavaScript

JavaScript 실습1

JavaScript 실습2

JavaScript 실습3

PostgreSQL_with_kakao_chatbot

챗봇 평점 남기기 기능 구현

  • 평가 점수를 입력받아 DB에 기록하고 평균 통계를 계산한다.

  • 단, 1사람당 1번씩만 평점 남기기가 가능하며 두 번째부터는 가장 최근 점수로 갱신된다.

  • 알고리즘

    • id 검색 후, 없을 경우 평가를 기록 = INSERT
    • id 검색 후, 있을 경우 평가를 갱신 = UPDATE
  • 코드 작성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import psycopg2
from datetime import datetime

passwd = '5280c3caeed8c1cb512f19d6fc238a6ab642556e69c3050ddfe232c4c4372d0e'
db = psycopg2.connect(host='ec2-3-234-131-8.compute-1.amazonaws.com', dbname='ec2-3-234-131-8.compute-1.amazonaws.com',user='ndurbfpbebgdrc',password= passwd,port=5432)
cur=db.cursor()

# 날짜, id, 점수
date_data = datetime.today().strftime('%Y-%m-%d')
id_data = "'ww'"
idid_data = 'ww'
score_data = '2'

# SELECT문 - id로 검색하여 조회
cur.execute("SELECT * FROM score WHERE id=%s;" % (id_data))
rows = cur.fetchall()
print(rows)
print(type(rows))

# rows 길이 = 0
# 해당 id가 남긴 기록이 없음 = 첫 평가
# 점수를 포함한 데이터를 INSERT
if len(rows) == 0:
cur.execute("INSERT INTO score (date, id, score) VALUES (%s, %s, %s);"
, (datetime.today().strftime('%Y-%m-%d'), idid_data, score_data) )

# rows 길이 != 0
# 해당 id가 남긴 기록이 있음 = 최소 두 번째 평가
# 기존에 남긴 점수를 새로 UPDATE
else :
cur.execute("UPDATE score SET date=%s, score=%s WHERE id=%s;"
, (datetime.today().strftime('%Y-%m-%d'),score_data, idid_data) )

# cur.execute("SELECT * FROM score WHERE id=%s;" % (id_data))
# rows = cur.fetchall()
# print(rows)
# print(type(rows))

# POSTGRESQL DB에 COMMIT 하기
# db.commit()
  • 챗봇 스킬로 사용 가능하도록 형식을 맞추어 다시 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# # db에 점수추가
@app.route('/api/dbinsert', methods=['POST'])
def dbinsert():
body = request.get_json() # 사용자가 입력한 데이터

# date_data = datetime.today().strftime('%Y-%m-%d')
id_data = "'%s'" %str(body['userRequest']['user']['id'])
idid_data = '%s' %str(body['userRequest']['user']['id'])
score_data = str(list(body['userRequest']['utterance'])[1])
cur=db.cursor()

cur.execute("SELECT * FROM score WHERE id=%s;" % (id_data))
rows = cur.fetchall()

if len(rows) == 0:
cur.execute("INSERT INTO score (date, id, score) VALUES (%s, %s, %s);"
, (datetime.today().strftime('%Y-%m-%d'), idid_data, score_data) )

else :
cur.execute("UPDATE score SET date=%s, score=%s WHERE id=%s;"
, (datetime.today().strftime('%Y-%m-%d'),score_data, idid_data) )

db.commit()

responseBody = {
"version": "2.0",
"template": {
"outputs": [
{
"simpleText": {
"text": "점수가 반영되었습니다.\n감사합니다."
}
}
]
}
}

return responseBody
  • 블록 제작
  • 별점 버튼을 점수 저장할 블록으로 연결

Untitled

  • 스킬 만들고 적용하기

Untitled

  • 실행 결과

Untitled

Untitled

PostgreSQL_on_Heroku

헤로쿠에서 PostgreSQL 사용하기

heroku에서 postgresql 설치

  • 내 홈페이지의 Resources로 들어가기

Untitled

  • Add-ons 에 postgres 검색

Untitled

  • Heroku Postgres설치를 위해 Submit Order Form 클릭
    Untitled

  • Heroku Postgres 클릭

    Untitled

  • 하면 현재 사용중인 DB현황을 볼 수 있다.

Untitled

pgAdmin에서 heroku 와 연동

  • pgAdmin 실행
    • 중간에 문제가 생긴다면ubuntu에서 service start를 해볼것

sudo service postgresql status

sudo service postgresql start

사용자 계정 Password 설정

  • 기본적으로 admin 사용자로 등록이 되어 있다. 보통 DB 초기 세팅 시에는 패스워드를 입력받아야 한다. ( password : 2016***** )

sudo passwd postgres

Untitled

  • Servers(우클릭) → Register → Server… → 클릭

Untitled

Untitled

  • General 탭의 Name 작성해주기

Untitled

  • Connection탭의 주소 작성해주기

    • Heroku 홈페이지의 Datastores → Settings → View CreDentials… 클릭

      Untitled

      ——> 양식에 맞춰 작성해주기

      Untitled

      ——> Save 클릭

  • 서버가 추가된것을 확인

Untitled

  • Heroku에서 대여해준 DataBase들 목록중에서 나의 DB를 찾아야함.

Untitled

Python으로 db에 데이터 입력하기

  • 테이블을 생성하고 데이터를 입력하는 python 코드 작성 후 실행

Untitled

Untitled

  • pgAdmin에서 확인

    • Query Tool 실행

    Untitled

    • test 테이블을 확인하는 쿼리 작성 후 실행

      Untitled

      ——> 성공!

python에서 db쿼리가 잘 작동하는지 확인

  • psycopg2 설치
1
pip3 install psycopg2-binary
  • 파이썬에서 test 테이블을 조회하는 코드를 작성 후 실행
  • python3 명령어로 실행

Untitled

Untitled

——> 성공!

최종 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# # 테이블 생성 + 데이터 집어넣기

import psycopg2

passwd = ''
db = psycopg2.connect(host='ec2-54-204-56-171.compute-1.amazonaws.com', dbname='d2p5j2up8o05rg',user='dywzgxybcyjnzu',password= passwd,port=5432)
cur=db.cursor()

# cur.execute("DROP TABLE test")

cur.execute("CREATE TABLE test (url varchar, title varchar);")

cur.execute("INSERT INTO test (url, title) VALUES (%s, %s);"
, ("google.com", "구글입니다") )

db.commit()

print("good")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# # 테이블 조회하기

import psycopg2

passwd = ''
db = psycopg2.connect(host='ec2-54-204-56-171.compute-1.amazonaws.com', dbname='d2p5j2up8o05rg',user='dywzgxybcyjnzu',password= passwd,port=5432)
cur=db.cursor()

cur.execute("SELECT * FROM test;")
rows = cur.fetchall()

print(rows)
print(rows[0][0])
print(type(rows))

Crawling data for chatbot

크롤링 - 인기종목 top5

  • 챗봇에 필요한 자료 수집 목적
  • 크롤링 코드를 먼저 작성하고 이후에 스킬 형태로 변환하여 사용할 예정

준비

  • 크롤링할 url 선택 : https://finance.naver.com/
  • 추출할 정보를 우클릭 → 검사
  • 표시된 html을 copy → copy selector

크롤링 코드

  • url과 copy selector를 이용하여 코드 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import requests
from bs4 import BeautifulSoup

import pandas as pd
import numpy as np
url = 'https://finance.naver.com/'

response = requests.get(url)
response.raise_for_status()
html = response.text
soup = BeautifulSoup(html, 'html.parser')
tbody = soup.select_one('#container > div.aside > div > div.aside_area.aside_popular > table > tbody')
trs = tbody.select('tr')
datas = []
for tr in trs:
name = tr.select_one('th > a').get_text()
current_price = tr.select_one('td').get_text()
change_direction = tr['class'][0]
change_price = tr.select_one('td > span').get_text()
datas.append([name, current_price, change_direction, change_price])

# print(datas)
df = pd.DataFrame(datas, columns=['종목명', '현재가', '등락', '전일대비' ], index=range(1, 6))
df = str(df)
print(df)
  • 결과

Untitled

크롤링 코드-2-

  • 앞의 코드를 조금만 바꿔보자
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import requests
from bs4 import BeautifulSoup

import pandas as pd
import numpy as np
url = 'https://finance.naver.com/'

response = requests.get(url)
response.raise_for_status()
html = response.text
soup = BeautifulSoup(html, 'html.parser')
tbody = soup.select_one('#container > div.aside > div > div.aside_area.aside_popular > table > tbody')

trs = tbody.select('tr')
datas = []
for tr in trs:
name = tr.select_one('a').get_text()
current_price = tr.select_one('td').get_text()
change_direction = []
if tr['class'][0] == "up":
change_direction.append("▲")
else:
change_direction.append("▼")
change_price = tr.select_one('span').get_text()
datas.append([name, current_price, change_direction, change_price])

# print(datas)
df = pd.DataFrame(datas, columns=['종목명', '현재가', '등락', '전일대비' ], index=range(1, 6))
df = str(df)
print(df)
  • 결과

Untitled

Crawling start for chatbot data

크롤링 기초

  • 크롤링한 데이터를 카카오 스킬을 통해 챗봇에 출력하도록 할 것이다
  • 우선 크롤링 기초를 연습하고 시작할 예정

사이트 정보 가져오기 - requests 사용법

1. requests 모듈 설치

  • VSCord에서 실행. 가상환경 진입 후 진행.
1
pip install requests

2. URL 요청하기 -get

  • status_code 는 응답코드를 가져온다.
  • text에는 HTML 코드가 담겨 있다.
1
2
3
4
5
6
import requests

response = requests.get('https://www.naver.com/')

print(response.status_code)
print(response.text)
  • status_code 의 응답코드는 200이 출력된다.
  • text의 HTML 코드는 다음과 같이 출력된다.

Untitled

사이트 정보 추출하기 - beaurifulsoup 사용법

0. BeautifulSoup가 필요한 이유

  • request.text를 이용해 가져온 데이터는 텍스트형태의 html.
  • 텍스트형태의 데이터에서 원하는 html 태그를 추출할 수 있을까?
  • 이를 쉽게 할 수 있게 도와주는 녀석이 바로 “뷰티풀수프”.
  • 즉, html을 수프객체로 만들어서 추출하기 쉽게 만들어준다.

1. beautifulsoup 설치

1
pip install beautifulsoup4

2.beautifulsoup 사용법

  • 정보를 추출할 사이트의 url 참고
  • 응답 코드가 200 일때, html 을 받아와 soup 객체로 변환
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import requests
from bs4 import BeautifulSoup

url = 'https://kin.naver.com/search/list.nhn?query=%ED%8C%8C%EC%9D%B4%EC%8D%AC'

response = requests.get(url)

if response.status_code == 200:
html = response.text
soup = BeautifulSoup(html, 'html.parser')
print(soup)

else :
print(response.status_code)

웹 크롤링 예제

  • 추출할 정보를 우클릭 → 검사
    • 다음과 같이 선택한 정보의 html이 표시된다

Untitled

  • 해당 html 우클릭 → copy → copy selector

Untitled

  • 복사한 copy selector를 붙여넣어서 코드 작성
    • copy selector 예시 : #s_content > div.section > ul > li:nth-child(1) > dl > dt > a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import requests
from bs4 import BeautifulSoup

url = 'https://kin.naver.com/search/list.nhn?query=%ED%8C%8C%EC%9D%B4%EC%8D%AC'

response = requests.get(url)

if response.status_code == 200:
html = response.text
soup = BeautifulSoup(html, 'html.parser')
title = soup.select_one('#s_content > div.section > ul > li:nth-child(1) > dl > dt > a')
print(title)

else :
print(response.status_code)
  • 다음과 같이 처음 지정했던 정보가 출력된다.

Untitled

텍스트만 출력

  • 텍스트만 뽑아오고 싶다면 get_text() 함수를 이용하면 됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import requests
from bs4 import BeautifulSoup

url = 'https://kin.naver.com/search/list.nhn?query=%ED%8C%8C%EC%9D%B4%EC%8D%AC'

response = requests.get(url)

if response.status_code == 200:
html = response.text
soup = BeautifulSoup(html, 'html.parser')
title = soup.select_one('#s_content > div.section > ul > li:nth-child(1) > dl > dt > a')
print(title.get_text()) # get_text() 이용하여 텍스트만 출력

else :
print(response.status_code)
  • 결과

Untitled

Kakao Chatbot Skill with GoormIDE

스킬 사용 : 구름 IDE

  • 구름 IDE를 이용한 스킬 사용 시도
  • 그러나 구름IDE는 서버 실행 후 해당 창을 종료하면 스킬 사용이 불가능 = 편의성이 떨어짐
  • 된다는 것만 확인하고 실제 챗봇 스킬에는 사용하지 않았다
  • 단, Heroku에 비해 난이도는 낮은 편이라 수월하다는 장점이 있었다

사전준비

  • 카카오 채널 생성
  • 카카오 챗봇 오픈 빌더 OBT 승인
  • 구름 IDE 가입 : https://ide.goorm.io/

컨테이너 생성

  • 구름 IDE 가입 후에 컨테이너를 생성한다.

Untitled

  • 생성 시 설정 : 이름, 설명, 공개범위 등
  • 추가 모듈/패키지 : 항목 모두 체크

Untitled

  • 생성 완료

Untitled

  • 컨테이너 실행

Untitled

파일 생성, 코드 작성

  • 파일 생성 : application.py
  • 랜덤으로 숫자를 생성하는 코드를 작성해본다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from flask import Flask, jsonify
import sys
import random
application = Flask(__name__)

@application.route("/")
def start():
return "Hello goorm!!!"

@application.route("/random", methods=["POST"])
def random_function():
response = {
"version": "2.0",
"template": {
"outputs": [
{
"simpleText": {
"text": str(random.randint(1,10))
}
}
]
}
}
return jsonify(response)

if __name__ == "__main__":
application.run(host='0.0.0.0', port=int(sys.argv[1]), debug=True)
  • 실행 : python [application.py](http://application.py/) 80
  • 서버가 작동한다.
  • 구름을 사용하는 동안에는 이 창을 종료해서는 안 된다.

Untitled

  • 컨테이너 관리 창에서 ‘설정으로 가기’

Untitled

Untitled

스킬 사용

Untitled

  • 블록에서 사용할 스킬을 설정한다.

Untitled

결과

  • 설정한 발화패턴 입력시 랜덤으로 숫자가 생성된다

Untitled

  • Reference

https://www.youtube.com/watch?v=EWK9G9XAk00&t=97s

Kakao Chatbot 스킬 사용

사전준비

  • Heroku 배포 이후에 진행
  • Hello world가 출력된 페이지를 띄어야 한다.

스킬 서버 구축 기본편

  • 스킬 서버에서 제공하는 2가지 API URI는 다음과 닽다.
  • 단순 텍스트형 응답 스킬
    • POST /api/sayHello
  • 단순 이미지형 응답 스킬
    • POST /api/showHello

(1) 스킬 서버 예제

  • 코드 작성 : main.py
    • 코드 print(body['userRequest']['utterance'])와 responseBody 영역은 추후 설명 할 예정이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
from flask import Flask, request
import json

app = Flask(__name__)

@app.route('/')
def hello_world():
return 'Hello, World!!!!!!!!!!!!!!!!!!!!!!!'

# 카카오톡 텍스트형 응답
@app.route('/api/sayHello', methods=['POST'])
def sayHello():
body = request.get_json() # 사용자가 입력한 데이터
print(body)
print(body['userRequest']['utterance'])

responseBody = {
"version": "2.0",
"template": {
"outputs": [
{
"simpleText": {
"text": "반가워!!!!! hello I'm Ryan"
}
}
]
}
}

return responseBody

# 카카오톡 이미지형 응답
@app.route('/api/showHello', methods=['POST'])
def showHello():
body = request.get_json()
print(body)
print(body['userRequest']['utterance'])

responseBody = {
"version": "2.0",
"template": {
"outputs": [
{
"simpleImage": {
"imageUrl": "https://t1.daumcdn.net/friends/prod/category/M001_friends_ryan2.jpg",
"altText": "hello I'm Ryan"
}
}
]
}
}

return responseBody
  • 코드 저장 후 배포 시 주의점
    • 경로에 주의해야 한다!
  • 배포 진행한다.
1
2
3
4
$ git add .
$ git commit -am "your_message" # 이 부분만 자유롭게 쓸 수 있다.
$ git push origin main ## Github Repository에 업데이트
$ git push heroku main ## Heroku 코드 배포

(2) 스킬 서버 등록

단순 텍스트형 응답

  • 아래와 같이 스킬 서버 정보를 입력하고 저장한다.
  • 코드에서 정의한 이름을 URL 뒤에 덧붙인다 : /api/sayHello

Untitled

단순 이미지형 응답

  • 텍스트형 응답과 같은 과정을 거친다.
  • /api/showHello

(3) 시나리오

  • 여기가 가장 중요하다. 이제 시나리오를 등록한다. 이 때 중요한 것은 파라미터 설정 탭에서 스킬 선택을 개별적으로 호출 할 수 있다.

단순 텍스트형 응답’ 스킬 사용

  • 봇 응답에서 스킬 데이터를 선택 후, 저장 버튼을 클릭한다.

Untitled

단순 이미지형 응답’ 스킬 사용

  • 사용할 스킬 데이터를 선택 후, 저장한다.

(4) 배포

  • 배포 탭을 클릭한 후, 배포를 진행

Untitled

(5) 테스트

  • 봇 테스트를 열고 아래와 같이 테스트를 한다.

  • 배포 완료 후 사용 가능

  • 단순 텍스트형 응답

    • 설정한 텍스트 출력
    • 정상 작동
  • 단순 이미지형 응답

    • 설정한 이미지 출력
    • 정상 작동

Untitled

(6) 로그 확인

  • Heroku 에서는 로그를 쉽게 확인 가능
1
heroku logs

(7) 출력

챗봇 빌더를 활용한 사칙연산 계산기 구현

  • 사칙 연산을 구현하는 챗봇을 만들어 본다.

(1) 엔티티 구성

  • 엔티티(Entity) : 봇이 이해할 수 있는 용어를 체계적으로 정리한 데이터 사전
  • 엔티티 구조는 = 엔티티명, 대표 엔트리, 동의어
  • 엔티티의 자세한 설명은 다음 링크에서 확인
  • 사칙연산을 예로 들면 아래와 같이 지정할 수 있다.
    • division, subtraction 등은 대표 엔트리를 말한다.
    • 동의어에 해당하는 값이 나오면 추후에 확인할 로그 값에는 대표 엔트리만 별도로 데이터를 수집할 수 있다.

Untitled

(2) 시나리오 구성

  • 엔티티를 구성했다면, 이제 시나리오를 구성한다.
  • 사용할 파라미터를 설정한다.

Untitled

  • 패턴 발화를 할 때 원하는 파라미터를 별도로 지정할 수 있다.
  • 패턴 발화를 보면 빨간색 네모 박스를 확인할 수 있는 데, 이 부분에서 파라미터를 설정할 수 있다.
  • 더하기, +에서의 파라미터는 엔티티 그룹을 설정하게 된다.

Untitled

  • 실제 파라미터 설정된 값은 다음과 같다.

Untitled

(3) 파이썬 코드

  • 이제 다음 코드를 작성하여 기존 main.py에 추가한다.
  • 코드 작성시, 한가지 유의 사항은 json.loads() 함수를 반드시 써줘야 한다. Python Dictionary를 String으로 변경하는 것은 str() 함수를 사용하면 쉽게 변경이 가능하지만, 문자열 dictionary를 Dictionary로 바로 변경은 되지 않는다. 따라서, json.loads()를 사용한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
from flask import Flask, request
import json

# 메인 로직!!
def cals(opt_operator, number01, number02):
if opt_operator == "addition":
return number01 + number02
elif opt_operator == "subtraction":
return number01 - number02
elif opt_operator == "multiplication":
return number01 * number02
elif opt_operator == "division":
return number01 / number02

app = Flask(__name__)

@app.route('/')
def hello_world():
return 'Hello, World!!!!!!!!!!!!!!!!!!!!!!!'

# 카카오톡 텍스트형 응답
@app.route('/api/sayHello', methods=['POST'])
def sayHello():
body = request.get_json() # 사용자가 입력한 데이터
print(body)
print(body['userRequest']['utterance'])

responseBody = {
"version": "2.0",
"template": {
"outputs": [
{
"simpleText": {
"text": "반가워!!!!! hello I'm Ryan"
}
}
]
}
}

return responseBody

# 카카오톡 이미지형 응답
@app.route('/api/showHello', methods=['POST'])
def showHello():
body = request.get_json()
print(body)
print(body['userRequest']['utterance'])

responseBody = {
"version": "2.0",
"template": {
"outputs": [
{
"simpleImage": {
"imageUrl": "https://t1.daumcdn.net/friends/prod/category/M001_friends_ryan2.jpg",
"altText": "hello I'm Ryan"
}
}
]
}
}

return responseBody

# 카카오톡 Calculator 계산기 응답
@app.route('/api/calCulator', methods=['POST'])
def calCulator():
body = request.get_json()
print(body)
params_df = body['action']['params']
print(type(params_df))
opt_operator = params_df['operators']
number01 = json.loads(params_df['sys_number01'])['amount']
number02 = json.loads(params_df['sys_number02'])['amount']

print(opt_operator, type(opt_operator), number01, type(number01))

answer_text = str(cals(opt_operator, number01, number02))

responseBody = {
"version": "2.0",
"template": {
"outputs": [
{
"simpleText": {
"text": answer_text
}
}
]
}
}

return responseBody
  • 코드를 저장 후 git배포한다.
  • 스킬 설정

Untitled

  • 스킬을 사용할 블록에서 스킬을 지정하고 챗봇 배포한다.

Untitled

  • 배포 후 카카오톡에서 직접 실험

  • (+) 연산 정상작동

  • (-)연산 정상작동

  • (x) 연산 정상작동

  • (%) 연산 정상작동

  • 사칙연산 모두 정상작동하므로 성공

Untitled