AI/Python

웹의 구조 이해: HTML / CSS / DOM

jumemory 2025. 5. 28. 18:15

크롤링과 웹 데이터 수집의 가장 밑바닥이 되는 핵심 개념

웹 크롤링을 제대로 이해하려면 먼저 알아야 하는 것이 있습니다.
바로 웹페이지가 어떻게 만들어져 있는가 입니다.

많은 초보자가 크롤링을 처음 배울 때 이렇게 생각합니다.

  • 그냥 화면에 보이는 글자를 가져오면 되는 거 아닌가?
  • Selenium이 알아서 다 해주는 거 아닌가?
  • BeautifulSoup에서 find()만 쓰면 끝 아닌가?

하지만 실제로는 그렇지 않습니다.
크롤링은 결국 웹페이지의 구조를 읽고, 그 구조 안에서 원하는 데이터를 정확히 찾아오는 작업입니다.

즉, 화면에 보이는 “중고차 가격”, “브랜드”, “주행거리” 같은 정보도
브라우저 안에서는 그냥 텍스트 덩어리가 아니라,
HTML 태그 구조 안에 배치된 데이터입니다.

그래서 이 파트에서는 다음을 중심으로 이해해야 합니다.

  • HTML은 무엇인가
  • CSS는 무엇인가
  • DOM은 무엇인가
  • 태그(tag), 속성(attribute), 텍스트는 어떻게 구분되는가
  • id와 class는 무엇인가
  • selector는 왜 중요한가
  • 개발자 도구에서 원하는 요소를 어떻게 찾는가
  • 정적 페이지와 동적 페이지는 어떻게 다른가

이 감각이 잡혀야 나중에:

  • BeautifulSoup의 find, find_all, select
  • Selenium의 find_element
  • 크롤링 대상 구조 분석
  • 사이트 구조 변경 대응

까지 자연스럽게 이해됩니다.


1. 웹페이지는 겉으로 보이는 화면이 아니라 “구조화된 문서”다

사용자가 브라우저에서 보는 화면은 단순 이미지가 아닙니다.
대부분의 웹페이지는 내부적으로 다음 요소들의 조합으로 만들어집니다.

  • HTML: 내용과 구조
  • CSS: 모양과 배치
  • JavaScript: 동작과 변화

즉, 웹페이지는 그냥 “화면”이 아니라
구조 + 스타일 + 동작으로 이루어진 문서입니다.

크롤링은 이 중에서도 특히 HTML 구조를 읽는 일과 깊게 연결됩니다.

예를 들어 어떤 상품 페이지에서 사용자가 보는 정보가:

  • 상품명
  • 가격
  • 리뷰 수
  • 판매자 정보

라고 해도, 크롤러는 이걸 사람처럼 눈으로 읽는 것이 아니라
HTML 안의 특정 태그와 속성을 기준으로 찾아냅니다.

즉, 크롤링은
사람이 화면을 읽는 방식이 아니라, 프로그램이 문서 구조를 읽는 방식입니다.


2. HTML이란 무엇인가?

2-1. 정의

HTML은 HyperText Markup Language의 약자입니다.
웹페이지의 구조와 내용을 표현하는 언어입니다.

쉽게 말하면:

  • 제목은 제목답게
  • 문단은 문단답게
  • 버튼은 버튼답게
  • 링크는 링크답게

표시하기 위해 문서에 “의미 있는 표시(markup)”를 붙이는 방식입니다.

즉, HTML은
웹페이지의 뼈대라고 생각하면 됩니다.


2-2. HTML은 태그(tag)로 구성된다

HTML은 보통 태그로 이루어집니다.

예:

 
<h1>중고차 목록</h1>
<p>브랜드별 매물을 확인하세요.</p>
 

여기서:

  • <h1>는 큰 제목
  • <p>는 문단

을 의미합니다.

즉, 태그는
이 내용이 어떤 역할을 하는지 알려주는 표시입니다.


2-3. HTML 태그의 기본 구조

대부분의 태그는 이런 형태를 가집니다.

 
<태그이름>내용</태그이름>
 

예:

 
<div>안녕하세요</div>
 

여기서:

  • <div> → 시작 태그
  • 안녕하세요 → 내용
  • </div> → 종료 태그

입니다.


2-4. 자주 보는 HTML 태그

크롤링에서 자주 보는 태그는 다음과 같습니다.

div

가장 많이 보이는 박스형 태그입니다.
웹페이지를 여러 구역으로 나눌 때 많이 씁니다.

span

짧은 텍스트 구간을 감쌀 때 자주 씁니다.

p

문단(paragraph)을 나타냅니다.

a

링크(anchor)를 의미합니다.

img

이미지를 의미합니다.

ul, ol, li

목록 구조를 나타냅니다.

table, tr, td

표 구조를 나타냅니다.

h1 ~ h6

제목 태그입니다.

즉, HTML 태그를 알면
웹페이지가 어떤 식으로 구성되어 있는지 훨씬 잘 읽을 수 있습니다.


3. 속성(attribute)이란 무엇인가?

태그는 단순히 이름만 있는 것이 아니라, 추가 정보를 가질 수 있습니다.
이걸 속성(attribute) 이라고 합니다.

예:

 
<a href="https://example.com">사이트 이동</a>
 

여기서:

입니다.

즉, 속성은
태그에 붙는 추가 설명 정보입니다.


3-1. 크롤링에서 자주 보는 속성

id

페이지 안에서 특정 요소를 구분하는 고유 이름처럼 쓰입니다.

예:

 
<div id="price">2500만원</div>
 

class

비슷한 역할을 하는 여러 요소에 공통 이름을 붙일 때 씁니다.

예:

 
<div class="car-item">...</div>
<div class="car-item">...</div>
 

href

링크 주소를 나타냅니다.

src

이미지나 외부 리소스 주소를 나타냅니다.

data-*

사이트에서 추가 정보를 숨겨 넣을 때 자주 씁니다.

즉, 속성은
텍스트만 보는 게 아니라 데이터의 위치와 의미를 찾는 단서가 됩니다.


4. CSS란 무엇인가?

4-1. 정의

CSS는 Cascading Style Sheets의 약자입니다.
웹페이지의 디자인과 스타일을 담당합니다.

즉:

  • 글자 크기
  • 색상
  • 여백
  • 배치
  • 박스 모양

같은 걸 정합니다.

HTML이 뼈대라면, CSS는 옷과 꾸밈에 가깝습니다.


4-2. 왜 크롤링에서 CSS를 알아야 하나?

크롤링할 때 CSS 자체를 깊게 작성할 일은 많지 않지만,
CSS 선택자(selector) 를 이해해야 원하는 요소를 정확히 찾을 수 있습니다.

예:

  • 특정 class를 가진 요소
  • 특정 id를 가진 요소
  • 특정 태그 안에 있는 하위 요소

를 찾을 때 CSS 선택자 감각이 중요합니다.

즉, CSS를 배우는 이유는
디자인을 하려는 게 아니라, 요소를 찾는 규칙을 이해하기 위해서입니다.


5. Selector(선택자)란 무엇인가?

5-1. 정의

Selector는
웹페이지 구조 안에서 원하는 요소를 지정하는 규칙입니다.

즉:

  • “이 태그를 찾아라”
  • “이 class를 가진 요소를 찾아라”
  • “이 id를 가진 요소를 찾아라”
  • “이 안에 있는 하위 요소를 찾아라”

를 표현하는 방식입니다.


5-2. 자주 쓰는 selector 예시

태그 선택자

 
div
 

→ 모든 div 태그

class 선택자

 
.car-item
 

→ class="car-item"인 요소들

id 선택자

 
#price
 

→ id="price"인 요소

하위 요소 선택자

 
.car-item .price
 

→ class="car-item" 안에 있는 class="price" 요소

이 selector 감각은 BeautifulSoup의 select()나 Selenium 요소 선택과 바로 연결됩니다.


6. id와 class는 무엇인가?

이 둘은 정말 자주 나오고, 초보자가 많이 헷갈리는 부분입니다.


6-1. id

id는 보통 한 페이지 안에서 특정 요소를 고유하게 구분할 때 씁니다.

예:

 
<div id="main-title">중고차 검색</div>
 

이론적으로는 한 페이지 안에서 같은 id가 여러 번 나오지 않는 것이 원칙입니다.

즉, id는
“이 요소 하나를 특정해서 가리키는 이름” 에 가깝습니다.


6-2. class

class는 비슷한 역할을 하는 여러 요소에 공통으로 붙입니다.

예:

 
<div class="car-item">첫 번째 매물</div>
<div class="car-item">두 번째 매물</div>
<div class="car-item">세 번째 매물</div>
 

이건 “차량 매물 카드”처럼 같은 종류의 요소를 묶는 이름입니다.

즉, class는
여러 비슷한 요소를 그룹으로 다루기 위한 이름입니다.


6-3. 차이 정리

id

  • 보통 하나를 가리킴
  • 고유 식별자 느낌

class

  • 여러 요소에 반복될 수 있음
  • 그룹 이름 느낌

크롤링에서는:

  • 페이지 전체 제목처럼 하나만 있는 요소 → id가 자주 유용
  • 매물 목록처럼 반복되는 요소 → class가 자주 유용

합니다.


7. DOM이란 무엇인가?

7-1. 정의

DOM은 Document Object Model의 약자입니다.
웹페이지의 HTML 문서를 트리 구조로 표현한 것입니다.

즉, HTML은 그냥 납작한 텍스트가 아니라
부모-자식 관계를 가지는 구조로 이해할 수 있습니다.

예:

 
<div class="car-item">
<span class="brand">현대</span>
<span class="price">2500만원</span>
</div>
 

이 구조에서는:

  • div가 부모
  • 그 안의 두 개 span이 자식

입니다.

즉, DOM은
웹페이지 구조를 나무(tree)처럼 보는 방식입니다.


7-2. 왜 중요한가?

크롤링은 단순히 텍스트를 찾는 것이 아니라,
어떤 요소가 어떤 요소 안에 들어 있는지를 읽는 일입니다.

예:

  • 매물 카드 안의 가격
  • 상세 영역 안의 주행거리
  • 목록 안의 링크

즉, DOM을 이해해야 “페이지 구조를 따라 내려가며 데이터 찾기”가 가능해집니다.


7-3. 부모 / 자식 / 형제 관계

DOM에서는 자주 이런 표현을 씁니다.

  • 부모(parent)
  • 자식(child)
  • 형제(sibling)

예:

 
<div class="car-item">
<span class="brand">현대</span>
<span class="price">2500만원</span>
</div>
 

여기서:

  • div는 부모
  • 두 span은 자식
  • 두 span끼리는 형제 관계

입니다.

이 감각은 나중에 BeautifulSoup 탐색이나 Selenium 선택에 직접 연결됩니다.


8. 개발자 도구(Developer Tools)란 무엇인가?

8-1. 정의

개발자 도구는 브라우저 안에서
현재 웹페이지의 HTML 구조, CSS, 네트워크, 스크립트 등을 볼 수 있는 기능입니다.

보통 크롬 기준으로:

  • F12
  • 또는 마우스 우클릭 → 검사(Inspect)

로 열 수 있습니다.


8-2. 왜 중요한가?

크롤링할 때 가장 먼저 하는 일이 바로 이것입니다.

“내가 원하는 데이터가 HTML에서 어디에 있는지 찾는 것”

예:

  • 가격이 어떤 태그 안에 있는지
  • 브랜드명이 어떤 class를 가지는지
  • 상세 링크가 어떤 href에 들어 있는지

이걸 개발자 도구에서 확인합니다.

즉, 개발자 도구는
크롤링 대상 구조를 해부하는 현미경 같은 도구입니다.


9. 개발자 도구에서 무엇을 봐야 하나?

9-1. 태그 구조

예:

  • div
  • span
  • a

어떤 태그로 감싸져 있는지 봅니다.


9-2. class / id

예:

  • class="price"
  • id="car-list"

이런 이름이 있으면 선택자 후보가 됩니다.


9-3. 반복 구조

차량 목록처럼 같은 형태가 반복되면 보통 크롤링하기 좋습니다.

예:

 
<div class="car-item">...</div>
<div class="car-item">...</div>
<div class="car-item">...</div>
 

이건 car-item을 반복적으로 수집하면 된다는 뜻입니다.


9-4. 실제 텍스트 위치

화면에 보이는 가격이
정말 HTML 텍스트로 들어 있는지,
아니면 JavaScript로 나중에 채워지는지도 봐야 합니다.

즉, 단순 구조뿐 아니라 데이터가 언제, 어떻게 들어오는지도 봐야 합니다.


10. 정적 페이지와 동적 페이지

이건 크롤링에서 매우 중요합니다.


10-1. 정적 페이지

정적 페이지는 서버가 HTML을 보낼 때
이미 필요한 데이터가 HTML 안에 포함된 경우입니다.

즉:

  • requests로 HTML 가져오기
  • BeautifulSoup로 파싱

만으로 충분할 때가 많습니다.


10-2. 동적 페이지

동적 페이지는 처음 HTML에는 데이터가 없거나 일부만 있고,
나중에 JavaScript가 실행되면서 데이터가 채워지는 경우입니다.

예:

  • 스크롤 내려야 추가 매물 로딩
  • 버튼 클릭해야 상세 정보 등장
  • 페이지 이동 없이 목록만 갱신
  • Ajax 요청으로 데이터 가져오기

이럴 때는 Selenium 같은 도구가 필요할 수 있습니다.


10-3. 왜 이 차이를 알아야 하나?

정적 페이지인지 동적 페이지인지에 따라
수집 전략이 완전히 달라지기 때문입니다.

  • 정적 페이지 → requests + BeautifulSoup 가능
  • 동적 페이지 → Selenium 또는 API 분석 필요

즉, 웹 구조 이해는 단순 HTML 공부가 아니라
어떤 도구를 선택할지 결정하는 기준이 되기도 합니다.


11. 크롤링 관점에서 “좋은 선택자”란 무엇인가?

크롤링할 때 아무 selector나 쓰면 안 됩니다.
좋은 선택자는 다음 특성을 가집니다.


11-1. 너무 넓지 않아야 한다

예:

 
div
 

이건 너무 넓습니다.
페이지 안의 모든 div를 다 잡을 수 있습니다.


11-2. 너무 취약하지 않아야 한다

예:

 
div:nth-child(7) > span:nth-child(2)
 

이런 건 구조가 조금만 바뀌어도 깨지기 쉽습니다.


11-3. 의미 있는 class/id를 활용하는 것이 좋다

예:

 
.car-item .price
 

이런 식으로 의미 있는 구조를 활용하면 더 안정적입니다.

즉, 좋은 선택자는
너무 포괄적이지도 않고, 너무 깨지기 쉽지도 않은 것입니다.


12. 범용적으로 꼭 알아야 하는 HTML 구조 감각

웹 크롤링뿐 아니라 웹 자동화, 테스트, 프론트엔드 이해까지 확장해서
꼭 알아두면 좋은 감각은 다음과 같습니다.


12-1. 페이지는 중첩 구조다

웹페이지는 납작한 텍스트가 아니라
태그 안에 태그가 들어가는 중첩 구조입니다.


12-2. 사람이 보는 것과 코드가 보는 것은 다르다

사람은 화면을 보지만,
코드는 HTML 구조를 봅니다.

즉, 크롤링은 “보이는 것”이 아니라 “구조”를 읽는 일입니다.


12-3. 이름이 중요한 게 아니라 구조가 중요하다

div, span만 보고는 의미가 모호할 수 있습니다.
그래서 class, id, 부모-자식 관계까지 함께 봐야 합니다.


12-4. 사이트 구조는 바뀔 수 있다

오늘 잘 되던 selector가
사이트 개편 후 깨질 수 있습니다.

즉, 크롤링 코드는 항상
“사이트 구조 변경 가능성”을 염두에 두고 짜야 합니다.


13. 범용적으로 확장하면 어디까지 이어질까?

이 파트는 중고차 프로젝트뿐 아니라 다음 주제까지 연결됩니다.

  • 쇼핑몰 상품 크롤링
  • 뉴스 기사 수집
  • 부동산 매물 수집
  • 채용 공고 수집
  • 웹 테스트 자동화
  • Selenium UI 테스트
  • 브라우저 자동화
  • API 분석 전 HTML 구조 확인

즉, HTML / CSS / DOM 이해는
특정 프로젝트 전용 기술이 아니라 웹 기반 데이터 수집 전반의 공통 기초입니다.


14. 실전에서 자주 만나는 구조 예시

예시 1. 목록형 구조

 
<div class="car-item">
<span class="brand">현대</span>
<span class="model">아반떼</span>
<span class="price">2500만원</span>
</div>
 

이런 구조에서는:

  • .car-item을 반복적으로 찾고
  • 그 안에서 .brand, .model, .price를 꺼내는 방식이 자연스럽습니다.

예시 2. 링크 구조

 
<a class="detail-link" href="/car/123">상세보기</a>
 

이런 구조에서는:

  • 텍스트보다 href 속성이 더 중요할 수 있습니다.

즉, 크롤링은 텍스트만이 아니라
속성 값도 자주 수집 대상이 됩니다.


예시 3. 이미지 구조

 
<img class="car-image" src="https://example.com/car1.jpg">
 

이런 구조에서는:

  • 이미지 자체가 아니라
  • src 값을 추출합니다.

즉, 태그 내용이 아니라 속성 값 수집도 중요합니다.


15. 개발자 도구로 구조를 보는 기본 순서

크롤링 대상 페이지를 처음 열었을 때는 보통 이런 순서로 보는 것이 좋습니다.

  1. 원하는 데이터가 화면 어디에 있는지 눈으로 확인
  2. 개발자 도구 열기
  3. 해당 요소 검사(Inspect)
  4. 태그 종류 확인
  5. class / id 확인
  6. 반복되는 구조인지 확인
  7. 부모-자식 관계 확인
  8. 텍스트인지 속성값인지 확인
  9. 정적 HTML인지 동적 로딩인지 감각 잡기

이 순서를 익히면 사이트를 처음 봐도 덜 막힙니다.

 

 

 

 

 

 

 

 

 

 

 

  •  

 

 

파이썬 실전: 데이터 크롤링부터 웹 앱 배포까지

문법을 배웠다면 이제 실전에 적용할 차례입니다. 웹상의 데이터를 수집하고, 이를 지도에 표시하며, 누구나 접속할 수 있는 웹 페이지로 만드는 전 과정을 알아보겠습니다.


1. 데이터 수집의 준비: 파일 및 라이브러리 관리

import zipfile
with zipfile.ZipFile("./이름_생년_성별_10000.zip", 'r') as f:
    f.extractall("./mydata")

 

# - 파일 목록보기
# os.listdir("./mydata")
#
# - 파일 옮기기
# import shutil
# shutil.move("./'드디어 SKT 유심 교체했어요'…한달이나 참았던 이유-2025-05-23 064009.txt", "./a/")

데이터를 다루기 전, 파일을 압축 해제하고 관리하는 방법부터 시작합니다.

  • 압축 풀기: zipfile 모듈을 사용하여 대량의 데이터를 한 번에 추출합니다.
  • OS 활용: os.listdir()로 파일 목록을 확인하거나 shutil.move()로 파일을 정리하며 수집된 데이터를 관리합니다.
import os #운영체제(OS: Operating System) 관련 기능을 사용할 수 있게 해주는 표준 라이브러리를 불러오는 거예요.
if not os.path.isdir("./lyrics"):
    os.mkdir("./lyrics")
f = open(f"./lyrics/{artist}-{title}.txt", 'w', encoding='utf-8') #utf -8 전세계의 언어를 표현하는 확장팩팩 ///인코딩 디코딩 파일 변환방식임
f.write(lyrics.strip()) #f.write()만 하면, 데이터가 **메모리(버퍼)**에만 잠깐 저장돼 있을 수 있어요
f.close() #f.close()를 해야 진짜 파일에 저장되고 → 시스템이 파일을 안전하게 닫고 정리해요.

2. 웹 크롤링의 핵심 원리

웹사이트는 우리가 배운 딕셔너리와 유사한 JSON 형태나 태그 기반의 HTML 구조로 이루어져 있습니다.

  • HTTP 통신 (Request & Response):
    • requests 패키지: 서버와 데이터를 주고받는 도구입니다.
    • GET: URL에 데이터가 노출되는 방식. 주소를 잘 활용하면 페이지 이동 크롤링이 쉽습니다.
    • POST: 데이터를 Payload(딕셔너리 형태)에 숨겨서 요청하는 방식. 보안이나 복잡한 조건이 필요할 때 씁니다.
    • 헤더(Headers) 설정: 서버가 접근을 거부(<Response [406]>)할 때, 브라우저인 척 위장하여 우회하기 위해 사용합니다.
    • Status Code: 응답이 성공(200)했는지 확인합니다. <Response [406]>이 뜨면 서버가 거부한 것이므로, **헤더(User-Agent)**를 설정해 브라우저인 척 위장(우회)해야 합니다.
    • .json(): 서버에서 받은 JSON 텍스트를 파이썬의 딕셔너리 형태로 자동 변환해 줍니다.
  • result = requests.post('https://www.starbucks.co.kr/store/getStore.do?r=4B5E8X6R0Q', data=payload).json()
  • 데이터 파싱 (BeautifulSoup):
    • HTML 구조에서 원하는 데이터를 추출할 때 bs4 라이브러리를 사용합니다.
    • .find(), .find_all()을 이용해 태그, 클래스, ID로 원하는 요소를 정확히 찾아낼 수 있습니다.
    • Tip: 우클릭이나 복사가 금지된 사이트는 **F12(개발자 도구) -> F1(설정) -> Debugger 섹션의 'Disable JavaScript'**를 체크하면 분석이 수월해집니다.

 

pip install bs4
from bs4 import BeautifulSoup 
bs = BeautifulSoup(r.text)
bs.find("div", class_="song_name")

 

.replace, .text를 활용하여 원하는 데이터를 출력할수있다(참고** BeautifulSoup의 .text는 태크를 제외하고 문자만 출력해준다)

  • String Methods: .split(), .strip(), .replace() 등 지저분한 데이터를 깨끗하게 만드는 법.

정규식도 사용가능


3. 실전 프로젝트: 멜론 가사 수집 & 스타벅스 지도

  • 데이터 저장: f.open(), f.write(), f.close()를 통해 수집한 텍스트를 파일로 저장하며, utf-8 인코딩을 사용하여 한글 깨짐을 방지합니다.
  • 지도 시각화 (Folium)
    • folium.Map으로 지도를 생성하고, folium.Marker로 수집한 위경도 좌표에 마커를 찍습니다.
    • popup(클릭 시), tooltip(마우스 오버 시) 옵션으로 정보를 표시합니다.
    •  
  • 객체 저장 (Pickle): 수집한 딕셔너리 데이터를 원본 그대로(바이너리 형식) 저장하고 나중에 다시 불러올(load) 때 사용합니다.

.add_to(seoul)

  • folium.Marker(...)로 만든 마커를 seoul이라는 지도 객체에 **추가(add)**합니다.
seoul.save("./starbucks.html")

그렇게 만들어진 seoul을 파일로 저장

import pickle
with open("./starbucks.pkl", 'wb') as f:
    pickle.dump(result, f)

result

pickle은 파이썬에서 파일은 원본 그대로(직렬화) 저장하는 모듈이다 

with open()은 파일을 열고 자동으로 닫아주는 방식이다 "./starbucks.pkl" 이라는 파일을 만들어서 w(쓰고),b(바이너리)로 저장한것을 f지정함  (*** pickle은 데이터를 이진(binary) 형식으로 저장하기 때문에 wb 모드를 써야 한다***)

 

  • dump는 "데이터를 저장해라"는 뜻이에요.
  • result라는 변수에 담긴 데이터를 파일 객체 f에 저장하는 거예요.
  • 즉, result를 starbucks.pkl 파일에 저장하겠다는 뜻이에요.
import folium.map


seoul = folium.Map(location=[37.55, 126.98], zoom_start=12)

 

seoul = folium.Map(location=[37.55, 126.98], zoom_start=12)

지도 시작위치를 지정해서 생성하고 seoul이라는 변수에 저장

 

with open("./starbucks.pkl", 'rb') as f:
    result = pickle.load(f)

아까 저장했던 피클을 복원해주는것

for store in result['list']:
    folium.Marker([store['lat'],
                   store['lot']],
                   popup=store['s_name'],
                  tooltip=store['s_name'],
                   icon=folium.Icon(color='blue', icon='info-sign'
                                     )).add_to(seoul)

리스트에 저장된 딕셔너리(매장)위치 정보를 지도에 나타낸다

 

map_data = st_folium(seoul, width=1000, height=1000)

st_folium을 통해서 서울 스타벅스 위치정보를 추가한 seoul이라는 지도를 앱에 표시하겠다.

 

for store in result['list']:
    folium.Marker([store['lat'], store['lot']], popup=store['s_name']).add_to(seoul)
store['lat'] 위도 (latitude)
store['lot'] 경도 (longitude) — 타이핑 실수로 보이며 보통 lng 또는 lon이어야 정확함
popup=store['s_name'] 마커 클릭 시 뜨는 말풍선에 표시할 텍스트 (가게 이름 등)

 

 

 


4. 파이썬 웹 앱 만들기 (Streamlit)

파이썬 코드만으로 빠르게 웹 페이지를 구축하는 도구입니다. streamlit run 파일명.py로 실행합니다.

  • 주요 기능: st.title(), st.write(), st.slider(), st_folium() 등을 활용해 앞서 만든 지도를 웹에 띄울 수 있습니다.( from streamlit_folium import st_folium
  •  웹 서버도 자동  streamlit run 파일명.py을 실행하면 만든 페이지를 열어볼수있다

5. 프로그래밍 심화 이론 (고급 기능 & 자료구조)

실전 코드를 더 유연하게 만드는 개념들입니다.

scores = [90, 85, 95, 88]
total_score = calculate_sum(*scores)

  • 가변 인자 (*args, **kwargs):
    • *args: 정해지지 않은 개수의 인자를 튜플로 받습니다. 일반 매개변수 뒤에 위치합니다.
    • **kwargs: 여분의 키워드 인자들을 딕셔너리로 받습니다. 매개변수 목록 가장 마지막에 위치합니다.
    • 언패킹: `*`는 시퀀스를 위치 인자로, `**`는 딕셔너리를 키워드 인자로 풀어 전달합니다. (사용하지 않는 값은 언더바 _를 사용하여 버립니다.)
  • 클래스(Class)와 자료구조:
    • 클래스: 객체를 만들기 위한 틀입니다. 메서드의 첫 파라미터는 자기 자신을 가리키는 self를 씁니다.
    • 스택(Stack): 후입선출(LIFO), 큐(Queue): 선입선출(FIFO).
    • 링크드 리스트(Linked List): 각 노드가 데이터와 다음 노드의 주소를 가지고 연결된 구조입니다.

 

# Node class
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

 

# Linked List class
class LinkedList:
    def __init__(self):
        self.head = None

 

    # Append a new node to the end of the list
    def append(self, data):
        new_node = Node(data)
        if not self.head:
            self.head = new_node
            return
        last_node = self.head
        while last_node.next:
            last_node = last_node.next
        last_node.next = new_node

 

    # Prepend a new node to the beginning of the list
    def prepend(self, data):
        new_node = Node(data)
        new_node.next = self.head
        self.head = new_node

 

    # Delete a node with the given data
    def delete(self, data):
        if not self.head:
            return

 

        if self.head.data == data:
            self.head = self.head.next
            return

 

        current_node = self.head
        while current_node.next and current_node.next.data != data:
            current_node = current_node.next

 

        if current_node.next:
            current_node.next = current_node.next.next

 

    # Display the linked list
    def display(self):
        elements = []
        current_node = self.head
        while current_node:
            elements.append(str(current_node.data))
            current_node = current_node.next
        return " -> ".join(elements) if elements else "비어 있음"

 

 

 

 

from urllib.parse import urlparse, urlencode, quote
import requests
from bs4 import BeautifulSoup
import re
import os
import pathlib

p = re.compile("playSong\(\'([0-9]+)\',([0-9]+)\)")

def my_request(url, method='get'):
    head = {'user-agent'
            : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0'}
    if method == "get":
        return requests.get(url, headers=head)
   
def search_id(title):
    payload = {
        'searchGnbYn' : ['Y'],
        'kkoSpl' :  ['Y'],
        'mwkLogType' : ['T']
    }
    payload['q'] = [title]

    # url 주소 생성
    url = host + urlencode(payload, doseq=True)

    # return url
    r = my_request(url)
    text = BeautifulSoup(r.text).find("div", class_="tb_list d_song_list songTypeOne").find_all("tr")[1].find("button","btn_icon play" )['onclick']

    return p.findall(text)[0][-1]

def save_lyrics(songid, path='lyrics'):

    r = requests.get(url)
    head = {'user-agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0'}

    r = requests.get(url, headers=head)
    bs = BeautifulSoup(r.text)
    lyrics = BeautifulSoup(str(bs.find("div", id="d_video_summary")).replace("<br/>", "\n")).text

    # if not os.path.isdir(f"./lyrics/{path}"):
    #     os.mkdir(f"./lyrics/{path}")
    # else:
    #     pass
    pathlib.Path(f"./lyrics/{path}").mkdir(parents=True, exist_ok=True)

    title = bs.find("div", class_="song_name").text.replace("곡명", "").strip()
    artist = bs.find("div", class_="artist").text.strip()
    f = open(f"./lyrics/{path}/{artist}-{title}.txt", 'w', encoding='utf-8')
    f.write(lyrics.strip())
    f.close()

 

 

 

 

분야별 주요 라이브러리 요약

  • 데이터 과학: Pandas(데이터 분석), NumPy(수치 계산), SciPy(과학 계산).
  • 시각화: Matplotlib, Seaborn.
  • 인공지능: TensorFlow, PyTorch, Keras, Scikit-learn.
  • 웹 개발: Django, Flask, FastAPI.
  • GUI/자동화: PyQt, Tkinter, 시스템 스크립팅.