웹페이지 업그레이드가 끝이 났다 ~! 얏호!

 

(5)에 이어서 이번에 시도했던 건

"JSON file 읽어와서 리스트로 만들기" 였다.

 

솔직히 이번꺼는 멘토님이 다 해주셨음... 크흠흠

마지막 멘토링이어서 그런지 원리를 설명해주시고 아예 코드를 다 짜주셨다.

 

JSON file을 읽어와서 리스트로 만드는 게 어려웠던 주요 원인은,

간단히 말하자면 내가 javascript로만 시도를 했기 때문이었다.

 

나는 JSON file이 뭐.. 인터넷에서 읽어오는 것도 아니고 동적 파일이니까,

CSS에서 이미지 파일 불러오듯이 javascript 내에서 불러오면 되는 거 아닌가? 라고 생각했지만...

아니었나보다... !

클라이언트가 동적파일 불러오듯이 불러올 수는 없고 통신을 하면서 파일을 읽어야 하는데, 그러려면

 

1. javascript에서 ajax 사용해서 불러오기

2. python에서 불러오기

 

두 가지 방법 중 하나를 사용해야 했다.

어떤 방법이 더 효율적이고 그런 건 없었지만 python이 더 쉬워서..? 직관적이어서...? 아니면 간단해서...?

기억이 잘 나지 않지만 암턴 파이썬을 이용하는 방식을 택했다.

 

그래서 멘토님이랑 같이(라고 쓰고 멘토님이 혼자,,) 멘토링 시간 동안 코드를 짰다.

 

그 때 참고했던 블로그들!

https://karl27.tistory.com/105
https://stackoverflow.com/questions/15321431/how-to-pass-a-list-from-python-by-jinja2-to-javascript

 

How to pass a list from Python, by Jinja2 to JavaScript

Let's say I have a Python variable: list_of_items = ['1','2','3','4','5'] and I pass it to Jinja by rendering HTML, and I also have a function in JavaScript called somefunction(variable). I am tr...

stackoverflow.com

https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/change_event
https://karismamun.tistory.com/66

 

Javascript - JQuery를 이용해서 Input 값 변경 실시간 감지

 Input 타입에는 여러 가지가 있습니다. select, checkbox, text, password 등 수 많은 타입을 내장하고 있는데, select나 checkbox 같은 경우에는 값의 변경을 단순히 onchange로도 확인할 수 있습니다. 다만, t..

karismamun.tistory.com

 

그래서 15분만에 json 파일을 읽어와서 javascript로 넘겨줄 수 있었고 ~

자동완성 리스트를 손쉽게 완성할 수 있었다!

 

1. 파이썬 코드

@app.route('/')
def home():
    with open('response_1645513518181.json', 'r', encoding='UTF-8') as f:
        json_data = json.load(f)
    
    airport_iata = []
    
    for e in json_data['data']:
        airport_iata.append(e['IATA코드'])
        
    return render_template('index.html',data=json.dumps(airport_iata))

2. javascript 코드

//JSON file로 만든 리스트를 읽어와서, 변수로 만들어준다.
var iata_list = {{ data|safe }}

//autocomplete function으로 적용해준다.
autocomplete(document.getElementById("airport"), iata_list)

여기서 끝내면 아쉬우니까 ㅎ_ㅎ 멘토링 이후로 몇 가지를 더 추가해서 완성을 했다.

 

공항의 IATA code, ICAO code, 한글명 모두를 자동완성 가능하게 만들기!

이 때, 다 섞여서 자동완성이 들어가면 넘 복잡스러우니까,

dropdown을 이용하여 먼저 IATA/ ICAO/ 한글명 중 선택을 하게 한 다음,

해당되는 리스트에서만 검색하도록 기능을 구현했다.

 

구현한 순서는

 

1. 리스트 구분해서 쏴주기 - 코드 쫌만 바꾸면 됐음, 매우 간단

2. dropdown 박스 만들기 - 검색하면 바로 나옴. 아래는 제일 도움을 받았던 블로그

https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_optgroup 

 

W3Schools online HTML editor

The W3Schools online code editor allows you to edit code and view the result in your browser

www.w3schools.com

3. dropdown 박스에서 select한 값에 따라, autocomplete가 적용되는 리스트를 바꿔주기

보통의 dropdown 박스는 그냥 select만 되고, 적용을 하려면 submit 버튼을 별도로 눌러줘야 하는 형태였다.

하지만 나는 submit 버튼 만들기 싫었고... 검색을 해봤다 (select dropdown list without sumbit 뭐 이렇게ㅋㅋㅋ)

결과적으로 dropdown option들 밑에 submit 버튼을 따로 만들지 않고, select ID에다가 onchange 함수를 덧붙여주면 되는 거였다!

아래는 참고했던 사이트 :)

https://stackoverflow.com/questions/44680808/how-to-submit-value-in-selectoption-without-submit-button

 

How to submit value in <select><option> without submit button.

This is my code: <form action="?sort=SELECTEDVALUEHERE" method="GET"> <select> <option value="1">Option 1 </option> <option value="2">Option 2 </option>...

stackoverflow.com

<form action="#">
      <select name="searchType" id="searchType" onchange="select_search_type()">
        <option selected>Select Search Type</option>
        <option value="IATAcode">IATA</option>
        <option value="ICAOcode">ICAO</option>
        <option value="airportName">Full name</option>
      </select>
</form>

 

아래는 dropdown에서 선택해서, onchange가 되면 가동되는 select_search_type() 함수.

      function select_search_type() {
        let searchType = $('#searchType').val()

          if (searchType == "IATAcode") {
          autocomplete(document.getElementById("airport"), iata_list);
        } else if (searchType == "ICAOcode") {
          autocomplete(document.getElementById("airport"), icao_list);
        } else {
          autocomplete(document.getElementById("airport"), name_list);
        }
      }

 

4. 그 다음, DB에서 공항 정보를 search하는 코드에 추가를 해줬다

코드의 글자수가 다르니 그것을 기준으로!

   if (len(airport_receive)) == 4:
        airport_info = db.airports.find_one({'icaoCode': airport_receive}, {'_id': False})
    elif (len(airport_receive)) == 3:
        airport_info = db.airports.find_one({'iataCode': airport_receive}, {'_id': False})
    else:
        airport_info = db.airports.find_one({'name_KR': airport_receive}, {'_id': False})

 

5. 추가로는, 검색 후 검색창과 검색 옵션이 초기화되는 기능도 소소하게 추가를 해줬다.

ID값으로 구분해서 없애주는거에서 아아아아주 살짝 헤맸는데 검색하니 바로 나옴...

//input값 지워주기
$('#airport').val('')
//select 초기화하기
$('#searchType').prop('selectedIndex',0)

결과

하... 너무 만족스럽다 ^^

이제 배포도 해봐야지~~~~~~~

(4)편에서 만든 웹페이지를 업그레이드하는 방향을 두 개 생각해봤다.

 

1. 구글맵에 복수 개의 마커 추가하기

2. 검색창에 자동완성기능 넣기

 

멘토링에서 1보다는 2를 추천해주셔서 시도해봤다.

 

내가 원하는 결과물은, 국토부 open API로 제공받은 세계공항코드 JSON 파일을

HTML 내에 import 해와서 이것을 raw data로 이용, 자동완성 기능을 완성하는 것이었다

 

그런데 JSON 파일을 HTML 내에 import 해오는 것부터 막혀서...

하루쯤 해보고 각이 안나와서 과정을 좀 수정했다!

 

1. list 형태로 자동완성기능을 만들어보기

2. 자동완성기능에 참조되는 list에 JSON 파일을 import 해보기

 

일단 1을 성공해서 올려본다...

 

검색어는 "make autocomplete in javascript" 이런 식으로 검색을 많이 했고

JQuery에 autocomplete 기능이 있는 것 같아 시도를 해봤는데 잘 먹히지가 않아서...

JQuery 사용하는 것은 깔끔하게 포기하고 ^^ 아래 링크에 들어있는 코드를 그대-로 복사 붙여넣기를 했다.

 

https://www.w3schools.com/howto/howto_js_autocomplete.asp

 

How To Create Autocomplete on an Input Field

W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.

www.w3schools.com

 

근데 처음 복붙 했을 때 바로 먹히지가 않았는데,

내가 원래 썼던 html 문의 골격 구조가 아래와 같이 되어 있었다.

<head>

</head>

<style>

</style>

<script>

</script>

<body>

</body>

 

위 코드를 그대로 복사-붙여넣기하여 기존에 있떤 구조의 style과 script, body에 넣었는데 작동이 안되는 것...

 

근데 위 링크를 보니 body 다음에 autocomplete를 위한 script가 있는게 아니겠는가?

그래서 내 html문의 body 밑에 script를 구조를 하나 더 만들고 그 아래에 코드를 붙여넣어봤다

 

그랬더니 작동이 됨,,,!!!!! (?????)

autocomplete 성공

지금 List 안에 있는 요소들이 나라 이름이라서 저렇다... 이제 JSON 파일 가져와서 List 바꾸는 작업을 할 것이다.

 

사실 내가 직접 코드를 짠 것도 아니고 복붙했는데 된거라 어리둥절하기도 하고 원리도 정확하게는 모르겠지만......

어쨌든..... 얼레벌레하게 성공.....

(2)에서 말했던 해야 할 과제들!

오늘 완성을 했다 ㅎ_ㅎ

 

일단 DB에 저장하는 코드는 어제 다 짰는데 공항 API 사이트에 너무 많이 접근해서....

내 서버가 막혀벌임ㅜㅜ

그래서 더이상 DB를 저장하지 못하고 오늘 와서 다시 저장을 했다

하다보니 이거 API 접근하는 데에 한계가 좀 있는 것 같다 ㅋㅋㅋㅋㅋ

118개 저장했더니 바로 또 끊겼음ㅠㅠ

 

일단 DB에 저장이 잘 되는 것은 확인이 되어서,

저장된 데이터들만 가지고 웹페이지 구축을 시작했다.

 

문제

가장 헤맸던 부분은 저 위 사진에서,

 

2. 웹페이지 구축하기

1) 검색한 공항을 DB에서 GET하여

 

라고 써놨는데 알고보니 GET으로 가져오는게 아니어서......ㅋ

그 부분에서 가장 많이 헤맸다 ㅠㅠ

 

클라이언트에서 설정한 변수를 GET을 통해 보내고 GET function이 실행되어서 DB에서 정보를 갖고오고,

갖고온 정보를 다시 클라이언트로 넘겨주려고 했는데

 

일단 클라이언트에서 설정한 변수를 GET으로 보내주는 것부터 안됐다 ㅋㅋㅋ

 

생각해보면 당연한 게 GET의 방향 자체가 서버 > 클라이언트니까...

클라이언트 > 서버로의 통신이 안되는게... 뭐... 당연한 거지...

 

그러면 POST로 받은 정보를 GET에서 그대로 가져올 수는 없을까? 해서

파이썬 전역 변수를 써봤는데 그게 먹히지를 않더라. 왤까??? 이건 멘토링할 때 질문해봐야겠음.

 

해결

이것저것 막 해보다가 결국 성공한 방법은 좀..어,,, 허무(?) 했는데... ㅠㅠㅎㅎ

 

서버의 POST 함수 내에서 클라이언트로 보내주면 되는거였다...

흐름이 어떻게 되냐하면

 

클라이언트에서 정보를 받아 서버에 넘김 > 서버가 DB에서 정보 찾아서 변수로 만들고 > 클라이언트로 넘겨줌

 

이 모든 과정이 POST 내에서 가능했는데, return이 있다는 것을 눈치채고 나서 성공을 했던 것 같다 ㅋㅋㅋ

메시지 대신 변수를 보내주면 되는거 아닌가...? 해서

변수를 보냈더니 우왁 ! 성공 !

 

결국 클라이언트에서 POST가 성공하면 이걸 해줘 ~ 내부에

1. 가져온 변수에서 정보 좀 받아줘~

2. 그 정보 가지고 지도 바꾸고,

3. 테이블에 내용도 바꿔주라

 

이렇게 수정을 해서 성공을 하였다 ~!

아 테이블 내용은 append가 아닌 수정(modify)를 하고 싶었는데 검색한 결과,

일단 테이블 내용을 .empty < 요 커멘드로 지우고 나서 바로 .append를 붙여주면 가능했다

 

여러모로 한국어로 검색하는 것보다 영어로 검색할 때 정답이 잘 나왔던 것 같음 ㅠㅠㅋㅋ

 

암튼 성공하니 몹시 뿌-듯

결과물

궁금한 점

1. 서버 구동하는 파이썬 코드 내에서 전역 변수를 설정해도 왜 다른 함수에서 인식을 못할까???

2. POST에서 정보랑 메시지 둘 다 클라이언트로 보내고 싶은데 왜 안될까,,,?

    return jsonify({'airport_info': airport_info})
    # return jsonify({'airport_info': airport_info}, {'msg': '찾기 완료!'})

주석 설정해놓은 걸로 보내면 변수 인식 자체가 안됐음ㅜㅜ

 

> 멘토링에서 알려주심

 

1. 전역변수 설정은 맨 처음부터 해야한다

from flask import Flask, render_template, request, jsonify

import requests, json
from bs4 import BeautifulSoup

app = Flask(__name__)

from pymongo import MongoClient
import certifi

ca = certifi.where()

예를 들어 위 코드에서 함수로 들어가기 전 app, ca 등이 전역변수가 될 수 있는 것.

그렇지만 전역변수를 설정하는 것은 비추하셨다.

왜냐하면 전역변수로 설정을 하게 되면 변수의 상태가 자꾸 바뀌게 되어서, 좋지 않다는 것!

무슨 뜻인가 하면... 처음 서버를 킬 때 전역변수는 받은 내용이 아무것도 없으니 [] < 이렇게 공백이다가, 

클라이언트와 통신하면서 전역변수에 [내용] < 이렇게 내용이 생기게 되는데,

공백-내용-공백-내용 이렇게 상태를 자꾸 변경하면 비효율적이고 컴퓨터 입장에서 좀 헷갈리는...? 그런 문제가 있다고 하셨다!

전역변수 설정은 가급적 하지 않는 것으로 ~! + 변하지 않는 상수에 대해서만 설정해주는 것으로!

 

2. 내용을 보낼 때는 한꺼번에 보내야 한다

#return jsonify({'airport_info': airport_info}, {'msg': '찾기 완료!'})
return jsonify({'airport_info': airport_info, 'msg': '찾기 완료!'})

위 코드의 주석처럼, {} <얘를 두 번 쓰는 게 아니라,

{} < 이 안에 컴마(,)를 이용해서 복수 개의 항목을 보내줘야 한다는 것.

Next Step

생각해보니 ICAO 코드로 공항을 찾는게 너무 구린 것 같아서 ㅋㅋㅋㅋ 이 부분 고민을 좀 해보려고 한다,,,

(심지어 IATA 코드가 더 유명함 ㅠ 차라리 IATA 코드로 찾는게 더 낫겠어...)

그치만 그 전에, 검색어를 자동완성하는 기능을 넣고 싶다.

그 검색하고 있는 알파벳과 앞자리 같은 애들을 쭉 보여주는,, 그런거,,,

아니면 한글명으로 검색했을 때 쭉 보여주는... 그런거...

https://lcw126.tistory.com/192

 

HTML+Java script (기초) geolocation Google Map Api 이용 (웹페이지에서 지도 보여주기)

<최종 화면> 블로그에서 음식점을 리뷰하고 거기 위치를 마커로 표시하는 것을 봤을 것이다. 그것처럼 브라우저에서 지도를 표시해보자. 우선 지도 API를 이용해야한다. 네이버-유료, 카카오-부

lcw126.tistory.com

제일 설명이 잘 되어있는 블로그!

 

문제 & 해결

너무 왔다갔다 하면서 코딩하느라 정확히 기억은 안나지만....

  • 읽어온 공항 정보의 longitude, latitude가 텍스트여서 위치정보로의 변환이 안되는 문제

해결: 구글에 'javascript string to number' 검색.

위치정보라 소숫점까지 읽어왔어야 했음.

parseInt(): 소숫점은 안읽어옴

Number(): 왠지 모르겠는데 안됨...

parseFloat(): 왠지 모르겠는데 됨...

 

  • 읽어온 공항 정보를 구글맵상의 위치정보로 변환이 안됐음

오류 코드가 있었는데 대충 못찾겠다는 오류. 문자여서 못찾나 했는데 바꾼 후에도 여전히 못찾음.

 

해결:

let airport_map = new google.maps.LatLng(lati_num, long_num);
 
> 이 코드가 단순 숫자를 구글맵상의 위치정보로 변환해주는 코드였음. 필수로 들어갔어야 했는데 빼먹었다...
 
  • 맵의 그림이 바뀌지를 않음

해결: 코드를 잘 뜯어보고 이해해서 성공할 수 있었음 ㅠㅠ

//공항의 위치 정보를 구글맵상의 위치정보로 변환해주고
let airport_map = new google.maps.LatLng(lati_num, long_num);

//처음 iniMap 함수로 만들어준 기본 Map을 ID로 부른 다음,
//이 map의 center값, zoom값 등을 바꿔주면
//map의 그림이 바뀌는 거였음
let map = new google.maps.Map(document.getElementById("map"), {
            center: airport_map,
            zoom: 12
                   })

결과물

'공항 찾기' 누르면 지도에 해당 공항이 뿅-뜨고, 마커가 추가된다

얏호~!

 

사실 마커들을 뿅뿅 추가하고 싶었는데 그건 잘 안되어서....

나-중에 한번 시도해보기로 하고

 

Next step

생각해보니 공항명을 검색하면 그걸 DB에 저장해서 끌고오는게 넘 비효율적인 것 같았다...?

일단 세계의 공항 정보들을 크롤링해서 DB에 다 저장해놓은 다음,

웹페이지에서는

1) 공항 검색 > 2) DB 상에서 일치하는 공항을 찾기 > 3) 해당 정보만 GET 해서 클라이언트에 넘겨주기

 

하면 되는 거 아닌가...?

 

그래서 생각해 본 다음 스텝!

1. 공항 DB 만들기

1) 국토교통부의 세계공항코드 JSON 파일을 읽어온다

2) for 문 돌려서 하나씩 세계공항코드를 받아와, 이것을 api 사이트에서 검색하게 한다

3) api 사이트에 검색해서 나온 정보들을 DB에 저장한다
> 2/22 기준, 여기까지 했는데... api 사이트 접속을 너무 많이 해서 접속 오류 뜨는 듯...? ㅜㅜ

 

 

2. 웹페이지 구축하기

1) 검색한 공항을 DB에서 GET하여

2) 클라이언트에 넘겨주고, 정보 표출해준다

기획한 프로젝트에서 가장 까다로웠던 부분은 지도에 저장한 데이터로 포인트를 찍는 것이었다.

갓구글에서는 API 데이터를 제공하지 않을까? 하는 생각에 구글링을 좀 해봤고

꽤 쉽게 관련된 정보를 얻을 수 있었다!!

 

https://lcw126.tistory.com/192

 

HTML+Java script (기초) geolocation Google Map Api 이용 (웹페이지에서 지도 보여주기)

<최종 화면> 블로그에서 음식점을 리뷰하고 거기 위치를 마커로 표시하는 것을 봤을 것이다. 그것처럼 브라우저에서 지도를 표시해보자. 우선 지도 API를 이용해야한다. 네이버-유료, 카카오-부

lcw126.tistory.com

잘 정리 되어있는 블로그 끌어오기

 

다만 위의 블로그에서는 웹페이지를 아예 새로 만들면서 구글맵을 끼워넣는 형식이라

만들어놓은 웹페이지에 구글맵을 깔고싶은 나랑은 아아아아아주 약간 달랐다

 

시도해본 결과 헤드 부분, style 아래, script 아래에 각각의 코드들을 붙여주면 됐다

아 style에 width랑 margin, initMap function 안에 zoom 값은 내가 웹페이지에 맞춰서 설정을 했다

<head>
	
    <script src="https://maps.googleapis.com/maps/api/js?key=개인API키&callback=initMap&libraries=&v=weekly"async></script>

    <style>
            #map {
                height: 400px;
                /* The height is 400 pixels */
                width: 70%;
                /* The width is the width of the web page */
                display: flex;
                margin: 20px auto 0px auto;
              }
    </style>
    
    <script>
            function initMap() {
                        // The location
                        const uluru = { lat: 37.558714, lng: 126.790467 };
                        // The map, centered at Uluru
                        const map = new google.maps.Map(document.getElementById("map"), {
                        zoom: 12,
                        center: uluru,
                        });
                        // The marker, positioned at Uluru
                        const marker = new google.maps.Marker({
                        position: uluru,
                        map: map,
                    });
                }
    <script>

</head>

그리고 body 부분에는 아래의 코드를 붙여줘야 했다.

Map을 붙이고 싶은 위치에다가 넣어주면 된다

<body>
	<div id="map">
	</div>
</body>

 

배운 점은 id에 대해 스타일 지정을 할 때에는 .으로 ID를 호출하는 게 아니라 #을 이용해야 한다는 점.

 

앞으로 시도해보고 싶은 것은

 

1. DB에서 가져온 데이터를 구글맵상에 표출되도록 하기

머리로는 initMap function에 ajax를 추가해준 후

데이터에서 가져온 longtitude, latitude를 const uluru = { lat: 37.558714, lng: 126.790467 };

이 안에 ${long} 머 이렇게 붙이면 될 것 같은데

해보니 안됐음... ㅠㅠ

 

2. 마커 붙이기

맨 위에 올린 블로그 보면 

- 마커 붙이는 법

- 여러 개의 마커를 표시해주는 법

도 나와있던데

 

그 중 내가 구현하고 싶은 기능은 여러 개의 마커를 표시하는 기능이다!

근데 자세히 보니 일단 마커를 붙인 후에 여러 개의 마커를 표시하는 쪽으로 발전시켜야 하는듯ㅋㅋㅋㅋ

 

암턴...

var pharmacys = [ ['희망약국', 위도, 경도] ['이수프라자약국', 위도, 경도] ]

뭐 이런 식으로 변수를 만든 후에 for 문을 이용하여 읽어오는 형태로 구현을 하면 되던데

 

그러면 DB 상의 데이터들을 같은 방식으로 for 문 돌려서 만들 수 있는거 아닐까,,,???


일단 1차적으로, ajax를 통해 DB에서 가져온 데이터를 표출시키는 것부터 연습해봐야겠다.

뜐뜐뜐,,,

 

아 visual studio code에서 html 주석을 다는 방법을 계속 찾아보는데 계속 안된다ㅠㅠ

1. 프로젝트 이름/ 간단 설명

<나의 공항 기록장>

항덕들을 위한 기록장,,, 방문했던 공항을 기록하고, 방문하고 싶은 공항도 찜할 수 있는 사이트!

2. 프로젝트 레이아웃

ICAO/ IATA letter를 검색하면 사진과 함께 풀네임, 공항이 위치한 국가 및 도시를 표시해준다.

기록하기 버튼을 누르면 아래 지도에 파란색 비행기로 아이콘이 그려지고

찜하기 버튼을 누르면 아래 지도에 빨간색 비행기로 아이콘이 그려진다.

3. 개발해야 하는 기능들

1) ICAO/ IATA 입력, 검색하면 이름, 국가/도시 표출해주기

2) 밑에 세계지도 띄우기

3) 위, 경도 좌표로 세계지도에 공항 아이콘 입력하기... (가능할까...?)

4. 필요한 데이터 소스

1) ICAO/ IATA 레터 - 공항 이름 - 국가/도시 - 위,경도 좌표

2) 세계 지도 (구글맵?)

 

1)이 가장 중요한 데이터라고 할 수 있는데, 사실 이 프로젝트의 시작점이기도 하다....

https://www.airport-data.com/api/doc.php

 

Airport-data.com - API Documents

API Documents Aircraft Thumbnail Request Request URLs for thumbnail look up are in the following format: https://www.airport-data.com/api/ac_thumb.json?m=XXXXXX&n=N https://www.airport-data.com/api/ac_thumb.json?m=400A0B&n=2 Parameters Name Value Example D

www.airport-data.com

https://www.airport-data.com/api/ap_info.json?icao=ABCD

https://www.airport-data.com/api/ap_info.json?iata=DEF

 

ABCD, DEF 자리에 ICAO, IATA 코드 입력해주면 공항 정보를 띄워주는 데이터 소스 사이트인데...

이것을 어떻게 활용할 방법이 없을까하여 생각해본 것!

 

덧붙여서, 프로젝트의 제 1 목표크롤링 및 DB 구축..!

https://www.airport-data.com/world-airports/icao-code/A.html

향후에 쓸 수도 있는 이 공항 정보들을 크롤링해서 DB에 저장한 뒤, 이를 활용하여 위 프로젝트를 만들고 싶다.

 

크롤링 하고 싶은 정보는

1. ICAO, IATA code

2. 위/경도 좌표

가 가장 중요한데, 따라서 이 정보들을 활용해서 뭐.. 그냥 영화 기록하기처럼 만들어도 되겠다...ㅎㅎㅎ

그건 일단 시작해보고 결정해야지...!

 

>> 만약 어렵다면!

 

https://www.data.go.kr/data/15061950/fileData.do

 

국토교통부_세계공항_코드_20201231

전세계 공항관련 하여 영문 공항명, 한글 공항명, 공항에 대한 ICAO 코드, 공항에 대한 IATA 코드 정보를 제공 합니다.

www.data.go.kr

국토교통부에서 제공하는 세계공항 코드 목록을 추가하여서

이런 식으로 자동완성이 되고, 검색하면 정보들이 뜨게 하는 사이트를 만들고 싶다!

1. 서버 업로드

1) 언제나 클라이언트의 요청에 응답하려면 컴퓨터가 항상 켜져 있어야.

2) 모두가 접근할 수 있는 공개 IP주소로 나의 웹서비스에 접근할 수 있어야.

 

1)을 위해 클라우드 환경을 구매한 후, 해당 클라우드를 활용한다!

AWS가 가장 널리 사용되는 클라우드 환경이다.

2. 서버 구매하기

AWS에서 클라우딩 컴퓨터를 구매하고, 인스턴스를 만들면 해당 컴퓨터에 서버가 만들어진다 !

구매시에 해야하는 몇 가지 설정들이 있었는데,

1) Create a new key pair 로 새로운 키페어 만들고, 다운로드하기

2) gitbash를 실행, 명령어에 아래를 입력해주기

ssh -i (키페어 끌어다놓기) ububtu@내IP주소

Key fingerprint 관련 메시지에 Yes 입력

3. 서버 세팅하기

1) python 언어 업그레이드, DB 설치, 명령어 통일을 해준다.

# python3 -> python
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 10

# pip3 -> pip 패키지 마법사 설치
sudo apt-get update
sudo apt-get install -y python3-pip
sudo update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1

# port forwarding localhost:5000 <여기서 5000 빼는 명령어
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 5000

2) filezilla를 통하여 새로운 사이트를 개설한다.

filezilla > 사이트 관리자 > New site > 프로토콜은 SFTP, 호스트는 배정받은 IP주소, 포트는 22, Key file 열어준다.

3) 새로운 사이트에 python파일과 html 파일을 업로드 해준다.

4. Flask 서버 실행

1) gitbash에서 명령어로 패키지를 설치해준다.

pip install flask
pip install dnspython

2) 서버의 5000포트를 열어준다.

인스턴스 선택 > 보안 그룹 > Edit inbound rules > 포트 추가

* 80포트가 HTTP 접속을 위한 포트고, 5000포트는 flask 접속을 위한 포트...

* 내 파일 > 80포트 > 5000포트로 연결되는 개념

5. nohup 설정

1) gitbash 종료 후에도 서버가 돌아가게 하기 위해 하는 설정이다.

gitbash 내에 이런 명령어를 입력해준다.

nohup python app.py &

2) 서버를 종료하고 싶다면?

ps -ef | grep 'python app.py' | awk '{print $2}' | xargs kill

6. 도메인 연결

도메인 주소와 IP주소간 연결을 시켜주는 단계.

 

1) 가비아 접속

2) 구매한 DNS 클릭하고 설정

3) 호스트 이름에 @, IP주소에 IP를 입력 (아래와 같이)

7. 주의할 점

서버 만들고 도메인 지정하는 방법은 그냥 해야할 때 PDF 파일을 참고하면 더 좋을 것 같다.

 

코드를 바꾼다면 :

먼저 gitbash에서 서버 연결을 끊어준 후, (5-(2) 참조)

Filezilla에 새로운 코드를 다시 업로드해줘야 함!

(엥 근데 해보니까 굳이 끊지 않고 업로드 해줘도 잘 반영됨)

 

8. 숙제 완성

팬명록을 완성하는 숙제. 몇 가지 기능을 덧붙여봤다!

 

아무 내용 없이 적어도 입력되는 문제가 있어서 (빨간 네모 부분)

 

닉네임과 응원댓글을 모두 적어야지만 DB에 저장되고 입력이 되고,

닉네임과 응원댓글 중 하나라도 빠지면 닉네임을 입력하세요! 혹은 코멘트를 입력하세요! 가 뜨도록 했다.

 

또 닉네임/ 응원댓글 중 하나만 쓴 경우 쓴 내용이 날아가지 않도록

새로고침을 하지 않는 코드도 추가했다!

 

수정된 app.py

def homework_post():
    name_receive = request.form['name_give']
    comment_receive = request.form['comment_give']

    if name_receive == "" :
        return jsonify({'msg': '닉네임을 입력하세요!'})

    elif comment_receive=="" :
        return jsonify({'msg': '코멘트를 입력하세요!'})

    else:
        doc = {
            'name': name_receive,
            'comment': comment_receive,
        }

        db.comments.insert_one(doc)
        return jsonify({'msg':'응원 완료!'})

수정한 index.html

        function save_comment() {

            let name = $('#name').val()
            let comment = $('#comment').val()

            $.ajax({
                type: 'POST',
                url: '/homework',
                data: {name_give: name, comment_give: comment},
                success: function (response) {
                    alert(response['msg'])
                    if (comment == "" || name == "") {

                    } else {
                        window.location.reload()
                    }

                }
            })
        }

 

결과적으로

뭐 대략 이렇게 ㅎㅎ

작은 변화지만 만족스럽다.

 

과제로 무엇을 만들어볼지 고민해봐야겠다.

서버와 파이썬 코드, html 코드를 연결하는 것을 배웠다

1. 환경 세팅 절차

1) 새 프로젝트 경로 설정해서 만들기

2) flask 라이브러리 설치

3) 프로젝트 폴더 (mars, homework 등등,,)에 경로로

   (1) templates - html

   (2) static - css, 이미지

   폴더 만들어주기

4) templates 안에 index.html

   프로젝트 폴더 안에 app.py 만들어주기

 

2. 설계 전 체크 사항

1) 클라이언트와 서버 연결 확인

    button onclick > function > app.py(api)에서 서버 연결 > 가동 을,

    버튼 눌러보면서 확인하는 것

2) 서버 만들기 : 코드에서 app.py

3) 클라이언트 만들기 : 코드에서 index.html (templates 안에 만드는거 잊지 않기!)

4) 완성 확인하기

3. POST

① 미리 지정해준 id를 갖고와서 새로운 이름을 만들어 준다

② 새로운 이름을 API와 약속한 대로 지정해준다

③ API가 (2)를 읽고, DB에 저장해준다. 완료되면 '주문 완료!'라는 메시지가 뜨게끔 할거다

    *dbprac.py에서 코드 따왔음. mongoDB에 저장하는 코드

④ 이 모든 과정이 success일 경우, response 함수를 실행해준다 (API에서 지정한 msg를 뜨게 함)

    * window.location.reload()는 새로고침 함수

4. GET

① DB로부터 데이터를 가지고 온다. html과 약속한 이름을 붙여준다.

② API와 약속한 이름으로부터 데이터를 받아온다.

    데이터를 읽고, 붙여줄 html 형태로 만든 다음 지정한 ID에 붙여준다.

 

 

*크롤링을 할 때 이런 방식으로도 읽어올 수 있다.

 title = soup.select_one('meta[property="title"]')

> copy-selector 방식으로는 'head > meta:nth-child(9)' 로 나오지만, 이 주소로 크롤링을 하려고 하면 None 이라고 뜬다.

> 언제 copy-selector 방식을 써야하고, 언제 property=""로 지정해줘야하는 방식을 써야하는지는 아직 모르겠...

 

5. 과제

예전 과제였던 팬명록을 업그레이드하는 과제를 했다.

닉네임과 응원 댓글을 남기면 업데이트해서 포스팅하는 형식!

과제를 하면서 조금 더 이해가 됐는데

POST: 클라이언트에서 정보를 얻어와서 DB에 저장한다.

GET: DB로부터 정보를 얻어와서 클라이언트로 보내준다.

즉, 'POST' = POST on DB, 'GET' = GET from DB 인 듯 하다.

 

이전 프로젝트들을 참고하면서 과제를 했고, 추가로는 '현재 기온'!

이 부분이 서울의 기온보다는 팬명록의 숫자가 되면 더 좋지 않을까? 하는 생각이 들어서 그렇게 추가로 업그레이드도 해봤다.

(length함수 쓰면 되는거라 쉬워서 따로 적지는 않겠음) 

 

결과물은 대충 이렇다 ㅎ

+ Recent posts