Data Scientist 옌

매일 발전하는 IT문제해결사

국비지원교육 (22.01-22.07)/강의노트

22-06-14(화) 094일차 [JavaScript, Node.js, Python] 객체 구조 분해, urllib 라이브러리, xml 파싱

옌炎 2022. 6. 24. 11:40
728x90

수업내용


1교시 (09:30-10:20)

  • script_13.html
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
	<h1>Destructuring</h1>
	<p>Open the console</p>
	<script type="text/babel">

		// 객체 구조 분해
		var sandwich = {
			bread: "더치 크런치",
			meat: "참치",
			cheese: "스위스",
			toppings: ["상추", "토마토", "머스타드"]
		}

		var {bread, meat} = sandwich

		console.log(bread, meat)

		bread = "마늘"
		meat = "칠면조"

		console.log(bread, meat)
		console.log(sandwich.bread, sandwich.meat)


		// 객체를 인자로 받는 함수
		var lordify = regularPerson =>
			console.log(`켄터베리의 ${regularPerson.firstname}`)

		var regularPerson = {
			firstname: "길동",
			lastname: "홍"
		}

		lordify(regularPerson)


		// 객체 인자 구조 분해
		var lordify_1 = ({firstname_1}) =>
			console.log(`켄터베리의 ${firstname_1}`)

		var regularPerson_1 = {
			firstname_1: "길동",
			lastname_1: "홍"
		}

		lordify_1(regularPerson_1)


		// 배열 구조분해
		var [firstResort] = ["용평", "평창", "강촌"]

		console.log(firstResort)


		// 배열 구조 분해(다른 예)
		var [,,thirdResort] = ["용평", "평창", "강촌"]

		console.log(thirdResort)

	</script>
</body>
</html>

2교시 (10:30-11:20)

  • script_14.html
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<title>Literal Enhancements</title>
	<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
	<h1>Literal Enhancements</h1>
	<p>Open the console</p>
	<script type="text/babel">

		// 객체 리터럴 개선
		var name = "탈락"
		var elevation = 9738

		var funHike = { name, elevation }

		console.log(funHike)


		// 함수를 포함하는 객체 리터럴 개선
		var name_1 = "탈락"
		var elevation_1 = 9738
		var print = function() {
			console.log(`${this.name_1} 산의 높이는 ${this.elevation_1} 피트입니다.`)
		}

		var funHike_1 = { name_1, elevation_1, print}

		funHike_1.print()


		// 예전 방식의 객체 리터럴

		var name_2 = "Léo Taillefer"
		var sound = "kahh"

		var skier = {
			name_2: name_2,
			sound: sound,

			powderYell: function() {
				var yell = this.sound.toUpperCase()
				console.log(`${yell} ${yell} ${yell}!!!`)
			},

			speed: function(mph) {
				this.speed = mph
				console.log('속력(mph):', mph)
			}
		}
		
		skier.powderYell()
		skier.speed("엉덩이에 불날 것 같은")
		console.log(JSON.stringify(skier))


		// 객체 리터럴 개선
		var name_3 = "Julia Mancuso"
		var sound_3 = "go fast"

		const skier_3 = {
			name_3,
			sound_3,

			powderYell_3() {
				let yell_3 = this.sound_3.toUpperCase()
				console.log(`${yell_3} ${yell_3} ${yell_3}!!!`)
			},

			speed_3(mph) {
				this.speed_3 = mph
				console.log('속력(mph):', mph)
			}
		}

		skier_3.powderYell_3()
		skier_3.speed_3(350)
		console.log(JSON.stringify(skier_3))
	</script>
</body>
</html>

  • script_15.html
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<title>Spread Operator</title>
	<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
	<h1>Spread Operator</h1>
	<p>Open the console</p>
	<script type="text/babel">

		// 스프레드 연산자

	    var peaks = ["대청봉", "중청봉", "소청봉"]
	    var canyons = ["천불동계곡", "가야동계곡"]
	    var seoraksan = [...peaks, ...canyons]

	    console.log(seoraksan.join(', '))


	    // .reverse()가 peaks 배열을 변경함

	    var peaks_1 = ["대청봉", "중청봉", "소청봉"]
	    var [last_1] = peaks_1.reverse()

	    console.log(last_1)
	    console.log(peaks_1.join(', '))


	     // peaks_2를 스프레드 연산자로 복사한 후 reverse 수행

	    var peaks_2 = ["대청봉", "중청봉", "소청봉"]
	    var [last_2] = [...peaks_2].reverse()

	    console.log(last_2) // 소청봉
	    console.log(peaks_2.join(', '))


		// 스프레드 연산자와 구조분해를 함께 사용
		var lakes = ["경포호", "화진포", "송지호", "청초호"]

		var [first, ...rest] = lakes

		console.log(rest.join(", "))


		// 스프레드 연산자로 인자를 배열로 바꾸기
		// 스프레드 연산자로 인자 중 일부를 배열로 받기

		function directions(...args) {
	      var [start, ...remaining] = args
	      var [finish, ...stops] = remaining.reverse()

	      console.log(`${args.length} 도시를 운행합니다.`)
	      console.log(`${start}에서 출발합니다.`)
	      console.log(`목적지는 ${finish}입니다.`)
	      console.log(`중간에 ${stops.length}군데 들립니다.`)
	    }

	    directions("서울","수원","천안","대전","대구","부산")


		// 객체에 대한 스프레드 연산자

		var morning = {
	      breakfast: "미역국",
	      lunch: "삼치구이와 보리밥"
	    }

	    var dinner = "스테이크 정식"

	    var backpackingMeals = {
	      ...morning,
	      dinner
	    }

	    console.log(backpackingMeals)
		
	</script>
</body>
</html>

3교시 (11:30-12:20)

  • 개발 생태계에 대한 설명

4교시 (12:30-13:20)

  • express_08.js
// Express 기본 모듈 불러오기
var express = require('express')
	, http = require('http')
	, path = require('path');

// Express의 미들웨어 불러오기
var bodyParser = require('body-parser')
	, static = require('serve-static');

// 익스프레스 객체 생성
var app = express();

// 기본 속성 설정
app.set('port', process.env.PORT || 3000);

// body-parser 미들웨어를 사용해 application/x-www-form-urlencoded 파싱
app.use(bodyParser.urlencoded({extended: false}));

// body-parser 미들웨어를 사용해 application/json 파싱
app.use(bodyParser.json());

// static 미들웨어 serve-static을 사용해 패스 매핑
// app.use('/public', static(path.join(__dirname, 'public')));
app.use('/public', static(path.join(__dirname, 'public')));

// 라우터 객체 참조
var router = express.Router();

// 미들웨어 파라미터 확인
// 라우팅 함수 등록
//			  /process/login/mike
router.route('/process/login/:name').post(function(req, res) {
	console.log('/process/login/:name 처리함');

	var paramName = req.params.name;
	/*
		POST 방식 : req.body.id
		GET 방식 : req.query.id
		POST/GET 방식 : req.body.id || req.query.id
	*/
	var paramId = req.body.id || req.query.id;
	var paramPassword = req.body.password || req.query.password;

	res.writeHead('200', {'Content-Type': 'text/html;charset=utf8'});
	res.write('<h1>Express 서버에서 응답한 결과입니다.</h1>');
	res.write('<div><p>paramName name : ' + paramName + '</p></div>');
	res.write('<div><p>Param id : ' + paramId + '</p></div>');
	res.write('<div><p>Param password : ' + paramPassword + '</p></div>');
	res.write("<br><br><a href='/public/lobin3.html'>로그인 페이지로 돌아가기</a>");
	res.end();
});

// 라우터 객체를 app 객체에 등록
app.use('/', router);

http.createServer(app).listen(3000, function(){
	console.log('Express 서버가 3000번 포트에서 시작됨');
});


5교시 (14:30-15:20)

  • 프로젝트 방법 및 산출물 설명 및 사례 공유

6교시 (15:30-16:20)

  • beautifulsoup_08.py
from bs4 import BeautifulSoup
import urllib.request as req
import urllib

'''
    ASCII EBCDIC 한글 UNICODE
    자바스크립트 url 인코딩 escape() 함수
'''
url = "https://ko.wikipedia.org/wiki/%ED%95%98%EB%8A%98%EA%B3%BC_%EB%B0%94%EB%9E%8C%EA%B3%BC_%EB%B3%84%EA%B3%BC_%EC%8B%9C"

# 파이썬에서 url 한글 인코딩 디코딩
str_unquote = urllib.parse.unquote('%ED%95%98%EB%8A%98%EA%B3%BC_%EB%B0%94%EB%9E%8C%EA%B3%BC_%EB%B3%84%EA%B3%BC_%EC%8B%9C')
print('str_unquote >>> : ', str_unquote)
str_quote = urllib.parse.quote('하늘과_바람과_별과_시')
print('str_quote >>> : ', str_quote)


res = req.urlopen(url)
soup = BeautifulSoup(res, "html.parser")

a_list = soup.select("#mw-content-text > div > ul > li a")

for a in a_list:
    name = a.string
    print("-", name)

  • beausoup_books.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<ul id="bible">
    <li id="ge">Genensis</li>
    <li id="ex">Exodus</li>
    <li id="le">Leviticus</li>
    <li id="nu">Numbers</li>
    <li id="de">Deuteronomy</li>
</ul>
</body>
</html>
  • beautifulsoup_09.py
from bs4 import BeautifulSoup

# http://localhost:8088/kosmoSpring/kos_beautifulsoup/beausoup_books.html
fp = open("beausoup_books.html", encoding="utf-8")
soup = BeautifulSoup(fp, "html.parser")

sel = lambda q : print(soup.select_one(q).string)
sel("#nu")
sel("li#nu")
sel("ul > li#nu")
sel("#bible #nu")
sel("#bible > #nu")
sel("ul#bible > #nu")
sel("li[id='nu']")
sel("li:nth-of-type(4)")

print(soup.select("li")[3].string)
print(soup.find_all("li")[3].string)

  • beausoup_frvege.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="main-goods" role="page">
    <h1>과일과 야채</h1>
    <ul id="fr-list">
        <li class="red green" data-lo="ko">사과</li>
        <li class="purple" data-lo="us">포도</li>
        <li class="yellow" data-lo="us">레몬</li>
        <li class="yellow" data-lo="ko">오렌지</li>
    </ul>
    <ul id="ve-list">
        <li class="white green" data-lo="ko">무</li>
        <li class="red green" data-lo="us">파프리카</li>
        <li class="black" data-lo="ko">가자</li>
        <li class="black" data-lo="us">아보카도</li>
        <li class="white" data-lo="cn">연근</li>
    </ul>
</div>

</body>
</html>
  • beautifulsoup_10.py
from bs4 import BeautifulSoup

# http://localhost:8088/kosmoSpring/kos_beautifulsoup/beausoup_frvege.html
fp = open("beausoup_frvege.html", encoding="utf-8")
soup = BeautifulSoup(fp, "html.parser")

print(soup.select_one("ul:nth-of-type(2) > li:nth-of-type(4)").string)
print(soup.select_one("#ve-list > li:nth-of-type(4)").string)
print(soup.select("#ve-list > li[data-lo='us']")[1].string)
print(soup.select("#ve-list > li.black")[1].string)

cond = {"data-lo":"us", "class":"black"}
print(soup.find("li", cond).string)

print(soup.find(id="ve-list").find("li", cond).string)

7교시 (16:30-17:20)

  • xml_make.py
from xml.etree.ElementTree import Element, dump, ElementTree

root = Element("xml", kind="language")

node1 = Element("first")
node1.text = "hi"
root.append(node1)

node2 = Element("second")
node2.text = "Hello"
root.append(node2)

#자료 출처 https://goo.gl/J8VoDK

def indent(elem, level=0):
    i = "\n" + level*" "
    if len(elem):
        if not elem.text or not elem.text.strip():
            elem.text = i + " "
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
        for elem in elem:
            indent(elem, level+1)
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
    else:
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = i
indent(root)
dump(root)

ElementTree(root).write('./data/note.xml')

  • test.xml
<?xml version="1.0"?>
<data>
<student>
    <name>peter</name>
    <age>24</age>
    <score math="80" english="97"/>
</student>
<student>
    <name>elgar</name>
    <age>21</age>
    <score math="67" english="56"/>
</student>
<student>
    <name>hong</name>
    <age>36</age>
    <score math="76" english="81"/>
</student>
</data>
  • xml_parsing.py
from xml.etree.ElementTree import parse

tree = parse('./data/test.xml')
root = tree.getroot()

student = root.findall("student")

name = [x.findtext("name") for x in student]
age = [x.findtext("age") for x in student]
score = [x.find("score").attrib for x in student]


print(name)
print(age)
print(score)

  • urlib_1_1.py
import urllib.request

url = "http://localhost:8088/kosmoSpring/img/img_mandu/ase.gif"
savename = "./data/ase.gif"
urllib.request.urlretrieve(url, savename)
print("저장되었습니다.")

8교시 (17:30-18:30)

  • 스프링 코드 버전업하기

Notes


728x90