티스토리 뷰

일단 글 시작하기 전

파이썬 한글 깨짐 해결법

 

참고: https://steady-coding.tistory.com/262

 

VS CODE에서 파이썬 한글 출력 오류 해결하기 [Python]

안녕하세요? 코딩중독입니다. 최근에 키움 open api를 이용한 주식 프로그램 개발 공부를 하고 있습니다. 그런데, 키움 서버에 보내는 정보나 받아 오는 정보가 한글인 부분도 있고, 다른 사용자에

steady-coding.tistory.com

나는 이 분이 하신거 따라하니까 해결됐음

 

index.py

#!python
import sys
import io

sys.stdout = io.TextIOWrapper(sys.stdout.detach(), encoding = 'utf-8')
sys.stderr = io.TextIOWrapper(sys.stderr.detach(), encoding = 'utf-8')

print("content-type: text/html; charset=utf-8\n")

파일 제일 상단에 이렇게 코드 추가해주니까 한글이 출력되었다.

 

이외에도 html코드를 print하는 부분에 아래 코드를 넣어줘도 해결된다고 한다. (나는 이걸로 안됐음..ㅠㅠ)

<meta charset="utf-8">

파이썬 특정 폴더의 파일명 가져오기, 파일 읽기, url 쿼리 가져오기 강의 시작!

급한 사람들은 아래에 [강의 추가 코드 요약 정리] 이렇게 되어있는 부분부터 보면 된다.

이런 글 목록을 index.py파일에 하나씩 하드코딩해주기에는 유지보수적인 측면에서 매우 비효율적이다.

따라서 이러한 title과 content를 동적으로 관리할 수 있다면 정말 편하겠지...

 

해당 글들을 관리하는 법은 제각각이지만, 이고잉님의 방법을 우선적으로 따라하기로 했다.

 

1. 콘텐츠를 저장할 폴더 생성 및 파일 생성

htdocs폴더 하위에 data라는 폴더를 생성 후

보여 줄 글들을 저장한다. 나는 txt파일로 생성했다.

 

예시) CSS.txt

Cascading Style Sheets(CSS)는 HTML이나 XML (en-US)(SVG, XHTML 같은 XML 방언(dialect) 포함)로 작성된 문서의 표현을 기술하기 위해 쓰이는 스타일시트 언어입니다. CSS는 요소가 화면, 종이, 음성이나 다른 매체 상에 어떻게 렌더링되어야 하는지 기술합니다.

CSS는 오픈 웹의 핵심 언어 중 하나이며 W3C 명세에 따라 브라우저끼리 표준을 맞춥니다. 레벨 단위로 개발한 CSS1은 더 이상 사용하지 않고, 다음 레벨인 CSS2.1은 권고안이며, 레벨보다 작은 단위인 모듈로 나뉜 CSS3은 표준화 과정을 밟고 있습니다.

해당 설명은 mozilla재단의 설명을 가져왔다. 아무 내용이나 상관없으니 편한대로 하자...

 

2. 원하는 폴더의 파일목록 이름을 가져오기

import os

#os 모듈 이용해서 data폴더에 있는 파일 명들을 가져온 후 files에 저장
files = os.listdir('data')

print(files)

files를 출력해보면 data폴더에 담겨있는 파일의 이름이 배열형태로 출력되는 것을 볼 수 있다.

싱기방기...

listStr = ''
for item in files:  # files에 있는 리스트들을 반복문을 통해 <li>로 만들어준다.
    listStr += '<li><a href="index.py?id={id}">{id}</a></li>'.format(id=item)

그리고 가져온 files 배열을 반복문을 통해서 li 태그로 만들어 준다. 자세한 내용은 생활코딩 파이썬 강의를 참고하시요...

간략히 설명하면 {id}라는 변수에 .format을 통해 files의 인덱스들을 차례대로 넣어준다.

 

그리고 listStr에는 내가 만든 파일의 개수만큼 <li><a>태그들이 문자열 형태로 들어있겠지...

모양이 궁금하면 for문이 끝난 후 print(listStr)를 해보면 된다!

 

3. 파일안에 담겨있는 내용 가져오기

 

import cgi,os	#기존의 os를 임포트해온 곳 옆에 cgi도 임포트 해오면 됨

form = cgi.FieldStorage()

pageId = form["id"].value
desc = open('data/'+pageId,'r', encoding='UTF-8').read()

form이라는 변수에는 cgi.FieldStorage()를 이용한다.

이것은 cgi에서 제공하는 양식 데이터를 얻을 수 있게 해주는 것이라고 한다. (아직 이해 제대로 안됐음ㅠㅠ)

 

지금 html코드를 보면 url 뒤에 id라는 변수를 이용해 요청을 처리하는 방식을 선택했다고 본다. (Get방식처럼)

ex) <a href="index.py?id={id}"> // URL: http://localhost/index.py?id=CSS

이처럼 id값에 해당하는 파일목록을 반환하는 느낌인데 이 url에 있는 id값을 가져올 수 있게 해주는 것이 cgi의 FieldStorage()함수가 아닐까... 해당 필드에있는 저장소를 가져오고

form["id"] 받아온 정보에서 key가 id에 해당하는 놈을 pageId로 받아오니까....

(내가 적었지만 정말 이해못하게 적어놓은 것 같다...^^ 나 혼자만 이해해버리기~~o((>ω< ))o)


너무 주절주절 적은 것 같아서 최선을 다해 최대한 깔끔하게 요약해보기로 함!

 

[파이썬 url 쿼리 가져오기]

1. 글 목록 및 내용을 폴더와 그 하위의 파일로 관리

2. 페이지를 변환하기 위해서 url 뒤 query에 id 값을 주어서 페이지를 구분할 수 있도록 한다.

   이 때, id값은 파일의 명과 동일하다.

3. cgi에서 제공하는 query의 값을 꺼내오는 방법은 아래와 같다.

form = cgi.FieldStorage()	# cgi에서 제공하는 함수를 통해 페이지에 있는 정보들을 가져옴

# form["id"].value	# 페이지의 정보가 담겨있는 form에서 id에 해당하는 정보의 value(값)을 가져옴

pageId = form["id"].value #이렇게 변수에 담으면 계속 활용할 수 있음
print("pageId: "+pageId)

4. pageId값이 잘 가져와졌는지 확인

pageId 변수에 내가 지정한 id 값이 뜨고, 해당 글 목록이 뜨는 것을 볼 수 있다.

(밑에 내용 안뜨더라도 일단 저 print문이 뜬다면 성공한 것임)

 

이 이후에는 가져온 id 쿼리 값과 file명 가져온 것, 파일 내용 가져온것 등을 활용한다.


4. if 조건문을 이용해 첫 실행 시 id값이 없을 때 보여줄 화면 구현

form = cgi.FieldStorage()
if 'id' in form:
    pageId = form["id"].value   # 자세한건 모르지만 url에서 ?뒤의 값을 가져올 수 있는 것 같음
    print("pageId: "+pageId)
    desc = open('data/'+pageId,'r', encoding='UTF-8').read()
else:
    pageId = "Welcome"
    desc = "Hello, Web"

이렇게 if문에 form안에 id값이 있는지 체크해서 id가 존재하지 않는다면 welcome화면을 보여줄 수 있도록 한다.


거의 다 끝났따~~~

헷갈릴테니까 이때까지 추가한 코드를 보쟈

[강의 추가 코드 요약 정리]

import cgi,os

# 1
files = os.listdir('data')
# 2
listStr = ''
# 3
for item in files:
    listStr += '<li><a href="index.py?id={id}">{id}</a></li>'.format(id=item)
# 4
form = cgi.FieldStorage()
# 5
if 'id' in form:
# 6
    pageId = form["id"].value
    desc = open('data/'+pageId,'r', encoding='UTF-8').read()
# 7
else:
    pageId = "Welcome"
    desc = "Hello, Web"

# ...이 이후에 print(html코드들)이 있음

다시 정리!! (위에 내가 쓴 글들이 마음에 안듦...)

# 1: os에서 제공하는 listdir함수를 이용해 data 폴더에 있는 파일리스트를 files라는 변수에 배열로 담아주기

# 2: 이제 files를 이용해 동적으로 <li>를 생성해 줄텐데 이걸 이용하기 위해 listStr이라는 문자를 담을 변수 선언

# 3: files배열을 이용해 반복문을 돌린다. (혹시 모르는 분 계실까봐 설명 추가)

    -> files배열의 길이는 3, 해당 반복문은 3번 실행 한 후 종료된다.
    반복문이 처음 실행될 때의 item 값은 files[0]의 값과 동일하다. 

    반복문이 돌아가면서 item은 files[1] files[2]와 같이 값이 들어가게 된다.

# 4: cgi에서 제공하는 페이지에 담긴 정보를 가져올 수 있는 함수를 이용해 form이라는 변수에 담는다.

# 5: 해당 form변수에 담겨있는 id값의 유무에 따라 조건문을 실행한다.

    -> 이유: 페이지를 처음 실행했을 때는 id값 없이 http://localhost/index.py로 실행되기 때문에 에러가 나기 때문.

# 6: pageId라는 변수에는 form의 id값을 가져온다.

    desc라는 변수에는 파이썬에서 제공하는 파일을 열 수 있는 open() 함수를 이용한다.
        -> 'data/'+pageId : 데이터 폴더의 pageId와 일치하는 파일을 연다. (pageId에 CSS가 들어있다면 CSS파일에 들어있는 내용을 읽어옴)

        'r': read, 해당 파일을 읽어온다. (이 외에도 다른 설정이 많음...지금은 읽어오는 용도만 필요하기때문에 'r'만 사용)

        encoding='UTF-8' : 해당 txt파일이 utf-8형식으로 저장되어있어서 decoding해올 때 에러가 나기때문에 형식이 utf-8이라고 다시 명시해주기 (txt파일을 ANSI로 변경해주면 해당 설정은 필요없다.)

        .read() : 앞의 open()에서 열어온 파일의 전체 내용을 문자열로 반환함 // .readline()이라는 함수를 사용하게 되면 파일의 첫번째 줄만 읽어오게 된다.

# 7: 만약 url의 query에 id값이 없다면 화면에는 welcome 페이지를 띄워준다.

 

html 코드를 보자

print('''
    <!doctype html>
    <html lang="ko">
    <head>
    <meta charset="utf-8">
    <title>web python </title>
    </head>
    <body>
    <h1><a href="index.py">Web</a></h1>
    <ol>
        {listStr}
    </ol>

    <h2>{title}</h2>
    <p>{desc}</p>
    </body>
    </html>
'''.format(listStr=listStr,title=pageId, desc=desc))

title에는 pageId값을, 글 목록에는 listStr을 설명란에는 desc를 넣어주었다.

(이제 와서 생각해보니 변수명을 헷갈리게 중복시켜놨네...>< 나쁜 코드! 수정해버리쟈)

print('''
    <!doctype html>
    <html lang="ko">
    <head>
    <meta charset="utf-8">
    <title>web python </title>
    </head>
    <body>
    <h1><a href="index.py">Web</a></h1>
    <ol>
        {list}
    </ol>

    <h2>{title}</h2>
    <p>{description}</p>
    </body>
    </html>
'''.format(list=listStr,title=pageId, description=desc))

완성~~


참고로 다른 설명보니까 파일을 open()해왔을 때

다시 close를 해오는게 추후에 안전할 것 같아서 코드를 추가해보았다.

#변경 전
desc = open('data/'+pageId,'r', encoding='UTF-8').read()

#변경 후
f = open('data/'+pageId,'r', encoding='UTF-8')
desc = f.read()
f.close()

index.py 전체 코드

#!python
import sys
import io

sys.stdout = io.TextIOWrapper(sys.stdout.detach(), encoding = 'utf-8')
sys.stderr = io.TextIOWrapper(sys.stderr.detach(), encoding = 'utf-8')

print("content-type: text/html; charset=utf-8\n")
import cgi,os

#os 모듈 이용해서 data폴더에 있는 파일 명들을 가져온 후 files에 저장
files = os.listdir('data')
listStr = ''
for item in files:  # files에 있는 리스트들을 반복문을 통해 <li>로 만들어준다.
    listStr += '<li><a href="index.py?id={id}">{id}</a></li>'.format(id=item)

form = cgi.FieldStorage()
if 'id' in form:
    pageId = form["id"].value   # 자세한건 모르지만 url에서 ?뒤의 값을 가져올 수 있는 것 같음
    f = open('data/'+pageId,'r', encoding='UTF-8')
    desc = f.read()
    f.close()
else:
    pageId = "Welcome"
    desc = "Hello, Web"

print('''
    <!doctype html>
    <html lang="ko">
    <head>
    <meta charset="utf-8">
    <title>web python </title>
    </head>
    <body>
    <h1><a href="index.py">Web</a></h1>
    <ol>
        {list}
    </ol>

    <h2>{title}</h2>
    <p>{description}</p>
    </body>
    </html>
'''.format(list=listStr,title=pageId, description=desc))

생활코딩 강의 주소

 

1. if문 추가

https://www.youtube.com/watch?v=Wb5jqLlPO7I 

 

2. list 동적 생성

https://youtu.be/v7UtxoqJ2bk

 

반응형
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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
글 보관함