-
SKN Family AI 15기 5월 4주차 회고(2)기록../SKN Family AI 15기 2025. 5. 23. 16:33
✍️5월 22일 학습 내용
변수 다루기
- 파이썬은 동적 타이핑을 통한 변수 재할당이 가능한 언어
- 다른 값을 여러 변수에 한 번에 할당할 수 있음
None 값
- 비어있거나 거짓인 상태를 나타내는 것이 아닌, 명시적으로 값이 없다는 표시
- return 문으로 명시적으로 값을 반환하지 않는 함수는 기본적으로 None을 반환한다.
- 함수 인자의 기본값이 없거나 기본값을 설정하고 싶지 않을 때 None으로 명시할 수 있다.
- 변수를 초기화시킬 때 할당할 값이 없다면 사용할 수 있다.
매개변수와 인자
- 매개변수는 함수 정의시 선언되는 것이고, 인자는 실제로 함수에 들어가는 그 값이다.
- 매개변수는 다음과 같은 방식으로 기본값을 설정할 수 있다.
def greet(name, location="서울"): #location을 "서울"로 기본 값을 주었습니다. #만약 별 다른 인자가 주어지지 않는다면, 서울로 출력됩니다. """주어진 이름과 장소로 인사를 생성합니다.""" print(f"안녕하세요, {name}님! 여기는 {location}입니다.") # 함수 내부에서는 name과 location을 일반 변수처럼 사용합니다.반복문 변수 제어
- continue 문을 만나면 해당 부분을 넘기고 다음 코드를 진행한다.
for i in range(2,10): if i < 5 : continue #5보다 작은 숫자는 건너뛰고 다음 문장을 출력한다. print(i)- pass 문을 만나면 아무 작업도 수행하지 않고 넘어간다.
- break 문을 만나면 그 즉시 반복을 중단한다.
while
- 조건 기반의 반복문
- 무한 반복을 유도할 수 있으니 사용에 유의할 것
while 조건식: # 조건식이 True인 동안 반복 실행될 코드 블록 (루프 본문) 실행문1 실행문2 # 중요: 루프 본문 내에서 언젠가는 조건식이 False가 되도록 # 상태를 변경하는 코드가 일반적으로 필요합니다. # while 루프가 종료된 후 (조건식이 False가 되면) 실행될 코드튜플
- 튜플은 여러 개의 데이터를 순서대로 묶어서 관리하는 데이터형으로, 소괄호로 묶어서 만듦.
- 불변한다는 특성을 가지고 있음.
- 함수에서 소괄호를 쓰는 이유 → 데이터가 변하지 않게 하기 위함
셋
- {} 로 묶어서 표시함. 딕셔너리와 비슷하지만 키와 값으로 묶이지 않고 데이터가 각각 독립적
- 중복 데이터를 허용하지 않음
- 순서를 보장하지 않음
- 셋에 저장되는 요소는 반드시 불변 타입의 데이터여야 함
- 주요 연산
- 합집합 .union(*다른_셋들)/+
- 차집합 .difference(*다른_셋들)/&
- 교집합 .intersection(*다른_셋들) /- *교집합은 빼기 연산. 연산 순서가 중요함
전역변수와 지역변수
- 함수 바깥에서도 사용할 수 있는 변수를 전역변수, 함수 내에서만 사용하는 변수를 지역변수라고 함
- 동일한 변수명이 있다면 함수 내에서는 지역 변수가, 그 외의 상황에서는 전역 변수가 우선시 됨 (지역변수는 다른 영역에서 인식되지 않음. 사라짐.)
- 함수 내에서 전역 변수를 선언하고 싶다면, global 키워드를 사용할 수 있다.
request모듈 사용하기
- request 모듈은 인터넷에 접속하여 정보를 요청할 때 사용하는 모듈
import requests #인터넷 접속을 위한 패키지지 url = "<https://www.melon.com/song/detail.htm?songId=37139110>" 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) r.textBeautifulSoup 모듈 사용하기
- 텍스트 형태의 데이터를 HTML에 맞게 출력함.
- 사용 예
from bs4 import BeautifulSoup bs = BeautifulSoup(r.text) print(bs)- find() 메소드
bs.find('div', class_="song_name") lyrics = BeautifulSoup(str(bs.find("div",id="d_video_summary")).replace("<br/>","\\n")).text lyrics.strip()OS 모듈 사용하기
- 운영 체제 관련 기능들을 파이썬 코드 내에서 사용할 수 있도록 다양한 함수와 변수를 제공하는 핵심 표준 라이브러리
- 아래 코드는 a.txt라는 파일을 쓰기모드로 열 수 있는 코드이다.
if not os.path.isdir("./lyrics"): os.mkdir("./lyrics") f = open("./lyrics/a.txt", 'w', encoding='utf-8')응용 : 특정 링크의 노래 가사를 작성하기
더보기import requests #인터넷 접속을 위한 패키지 from bs4 import BeautifulSoup url = "<https://www.melon.com/song/detail.htm?songId=37139110>" 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) print(r.text) bs = BeautifulSoup(r.text) print(bs) lyrics = BeautifulSoup(str(bs.find("div",id="d_video_summary")).replace(" ","\\n")).text title = bs.find("div", class_="song_name").text.replace("곡명","").strip() artist = bs.find("div", class_="artist").text.strip() if not os.path.isdir("./lyrics"): os.mkdir("./lyrics") f = open(f"./lyrics/{artist}-{title}.txt", 'w', encoding='utf-8') f.write(lyrics.strip()) f.close()✍️5월 23일 학습 내용
멜론에서 곡 이름을 검색하고, 해당 곡의 id를 통해 가사를 저장하는 코드
가사를 저장하는 함수
import requests from bs4 import BeautifulSoup import os def save_lyrics(songid, path='lyrics'): url = f"<https://www.melon.com/song/detail.htm?songId={songid}>" 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(" ", "\\n")).text if not os.path.isdir(f"./lyrics/{path}") and path != 'lyrics': os.mkdir(f"./lyrics/{path}") 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()- 해당 함수는 노래 가사 링크의 뒤에 들어오는 song_id를 매개변수로 받아 해당 곡의 가사를 추출하는 함수이다.
from urllib.parse import urlparse, urlencode, quote def search_id(title): host = "<https://www.melon.com/search/total/index.htm?"> payload = { 'searchGnbYn' : ['Y'], 'kkoSpl' : ['Y'], 'mwkLogType' : ['T'] } payload['q'] = [title] #사용자가 넘겨준 제목을 검색어로 사용함 url = host + urlencode(payload, doseq=True) return url- payload['q'] = [title]라는 코드는 사용자가 넘겨준 ‘제목’을 매개로 사용하여서 검색하겠다는 의미이다.
- 이 함수를 사용하면, 해당 노래의 urlcode를 이용하여 host와 결합해 해당 노래의 가사가 있는 링크를 반환한다.
url = search_id("너의 의미") #받은 url에 head 정보를 함께 넘겨주는 함수 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)r= my_request(url, 'get') bs = BeautifulSoup(r.text) bs.find("div", class_="tb_list d_song_list songTypeOne").find_all("tr")[1].find("button","btn_icon play" )- 결과
💡
<button class="btn_icon play" onclick="searchLog('web_tot','SONG_SONG','SO','너의 의미','4646573');melon.play.playSong('26020101',4646573);" title="재생" type="button"><span class="odd_span">재생</span></button>
- 아래 코드는 정규 표현식을 통해 playSong 뒤로 이어지는 숫자를 추출하는 코드이다.
- playSong('26020101',4646573) 부분에서 숫자 아이디를 추출하게 될 것이다.
import re #정규표현식을 사용할 수 있는 파이썬 내장 모듈. p = re.compile("playSong\\(\\'([0-9]+)\\',([0-9]+)\\)")💡
실행 결과
'4646573’
- 참고로 모든 숫자를 출력하도록 설정하면 리스트 안에 리스트 형태로 두 개의 숫자가 들어있다.
- 아이디로 사용될 건 첫번째 리스트에서 마지막 숫자 문자열이므로, 해당 문자열을 사용하여 코드를 작성한다. </aside>
- 위에 적은 내용들을 응용해서 하나의 모듈로 만들어보자
from urllib.parse import urlparse, urlencode, quote import requests from bs4 import BeautifulSoup import re def search_id(title): host = "<https://www.melon.com/search/total/index.htm?"> payload = { 'searchGnbYn' : ['Y'], 'kkoSpl' : ['Y'], 'mwkLogType' : ['T'] } payload['q'] = [title] #사용자가 넘겨준 제목을 검색어로 사용함 url = host + urlencode(payload, doseq=True) #노래 제목을 키워드로 검색하여 url을 생성 r = my_request(url, 'get') #header가 붙어 크롤링이 가능할 수 있도록 하는 코드 생성 bs = BeautifulSoup(r.text) target = bs.find("div", class_="tb_list d_song_list songTypeOne").find_all("tr")[1].find("button","btn_icon play" ) target = str(target) #크롤링 후 필요한 정보를 사용하기 위한 전처리 p = re.compile("playSong\\(\\'([0-9]+)\\',([0-9]+)\\)") # 해당 페이지에서 숫자로 된 song id를 찾아온다. return p.findall(target)[0][-1] #받은 url에 head 정보를 함께 넘겨주는 함수 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)my_song = search_id("200%") print(my_song) #다양한 노래의 아이디를 얻을 수 있게 되었다!- 이제 song_id를 알고 있으니 song_id를 통해 가사 url을 찾아 가사를 저장할 수 있게 되었다.
song_id를 통해 가사를 저장하기
import requests from bs4 import BeautifulSoup import os def save_lyrics(songid, path='lyrics'): url = f"<https://www.melon.com/song/detail.htm?songId={songid}>" # songid를 사용해서 가사 url을 검색한다. r = my_request(url, 'get') bs = BeautifulSoup(r.text) lyrics = BeautifulSoup(str(bs.find("div", id="d_video_summary")).replace(" ", "\\n")).text if not os.path.isdir(f"./lyrics/{path}") and path != 'lyrics': os.mkdir(f"./lyrics/{path}") 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()가사가 잘 저장되었다 b
응용 : 뉴스 기사의 링크를 입력하면, 그 뉴스의 제목을 이름으로 하고 내용을 저장하는 텍스트 파일을 만들어 저장하자.
import requests from bs4 import BeautifulSoup import os import pathlib import re def news_save(link, path='news'): url = link # 입력한 기사를 통해 크롤링 r = my_request(url, 'get') bs = BeautifulSoup(r.text) bs.find("span",class_= "end_photo_org").decompose #웹 크롤링에서 제일 중요한건 해당 객체의 속성과 이름입니다. text = BeautifulSoup(str(bs.find("div", id="newsct_article", class_="newsct_article _article_body")).replace("<br/>", "\\n")).text time = bs.find('div', class_='media_end_head_info_datestamp').find("span")['data-date-time'].replace(":","") if not os.path.isdir(f"./{path}") and path != 'news': os.mkdir(f"./{path}") title = bs.title.text.strip() safe_title = re.sub(r'[\\\\/:*?"<>|]', '', title) time = str(time) pathlib.Path(f"./{path}").mkdir(parents=True, exist_ok=True) f = open(f"./{path}/{safe_title}-{time}.txt", 'w', encoding='utf-8') f.write(text.strip()) f.write(time.strip()) f.close() return 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)파일을 읽어, 여성의 수와 남성의 수 구하기.
- 이 코드는 다음 코드들을 응용하여 완성시킬 수 있습니다.
import os os.listdir("./mydata") #해당 폴더에 들어있는 파일 목록들을 "리스트"형식으로 출력합니다.with open("./mydata/"+os.listdir("./mydata")[1], 'r') as f: print(f.read()) #리스트화 한 파일의 내용을 읽어냅니다.sum(map(lambda x : int(x.replace(",","")),['1,000', '2,300', '3', '4'])) # 리스트 내용을 맵핑한 후 모두 더할 수 있습니다.완성
male =0 female =0 gender_list = os.listdir("./mydata") asset_list_f = [] asset_list_m = [] for i in range(len(gender_list)): if int(gender_list[i][-11]) % 2 ==0: female+=1 with open("./mydata/"+os.listdir("./mydata")[i], 'r') as f: x = f.read() asset_list_f.append(x) else: male+=1 with open("./mydata/"+os.listdir("./mydata")[i], 'r') as f: x = f.read() asset_list_m.append(x) man_total = sum(map(lambda x : int(x.replace(",","")),asset_list_m)) man_avr = man_total // male woman_total = sum(map(lambda x : int(x.replace(",","")),asset_list_f)) woman_avr = woman_total // female print(f"""리스트에서 여성은 = {female}명, 남성은 {male}명입니다.\\n 여성의 평균은 {woman_avr: ,}이고, 남성의 평균운 {man_avr: ,}입니다. """) #위에 적은 f스트링은 천 단위로 자릿수를 끊어 표기하는 문법입니다. 참고하면 좋겠죠!!
✍️종합 회고
KEEP:
- 전공 지식이 어느 정도 도움이 되고 있고, 실습을 잘 따라가고 있다.
- 실습 도중 남은 시간에는 실습으로 완성한 코드를 살짝 수정해서 응용하거나 출력을 다르게 해보며 프로그램을 익히고 있다.
PROBLEM:
- 가끔 환경 변수 문제인지 kernel이 잘 연결되지 않는 경우가 있다. 필요하면 환경을 재설정할 필요가 있을듯?
- 강사님과 상호 작용을 잘 못한 것 같다!!
TRY:
- 세팅 환경 다음주에 다시 확인해보기
- 좀 더 적극적으로 말하기
'기록.. > SKN Family AI 15기' 카테고리의 다른 글
SKN Family AI 15기 6월 3주차 회고 (0) 2025.06.24 SKN Family AI 15기 6월 2주차 단위 프로젝트 회고 (0) 2025.06.15 SKN Family AI 15기 6월 1주차 회고 (1) 2025.06.08 SKN Family AI 15기 5월 5주차 회고 (0) 2025.05.27 SKN Family AI 15기 5월 4주차 회고(1) (0) 2025.05.20