본문 바로가기

SK네트웍스 Family AI캠프 10기/Daily 회고

11일차. Git & Streamlit & Crawling

더보기

 

11일 차 회고.

 

 프로젝트에서 의사소통이 제일 중요하다는 사실을 다시 깨닫게 되었다. 팀원끼리 의사소통을 통해 진행 상황을 전달받고 잘 진행되고 있는지 확인하는 것이 제일 중요하다고 생각한다. 이것이 우리 팀에게 부족하다는 것을 깨달았고, 팀장으로서 이를 주도해야 해서 많이 힘들었던 것 같다.

 

 

 

 

1. Git

 

 

1-1. Github Repository 생성

 

Github의 Repository 탭에서 'New'를 선택하여 새 Repository를 생성한다.

 

 

1-2. Clone Repository

 

VS Code에서 작업할 것이기 때문에, VS Code와 Repository를 연결한다.

연결할 Github의 코드(HTTPS)를 복사하면 된다.

 

 

1-3. Branch

 

Repository를 생성하면 기본적으로 만들어지는 branch는 'main'이다.

이는 개발을 최종적으로 완료했을 때 사용하는 branch로, 그 외에는 develop 또는 feature branch를 사용한다.

좌측 하단의 'main'을 누르고, 'Create new branch from...'를 선택하여 branch 이름을 작성한다.

branch 이름은 'develop' 또는 'feature-(feature name)'로 작성하는 것이 좋다.

 

 

1-4. Merge

 

merge는 작업 내용을 합칠 branch에서 진행한다.

즉, feature branch에서 작업한 내용을 develop branch로 merge 할 때는 develop branch에서 merge를 진행한다.

해당 branch를 선택한 상태에서  'Source Control' 탭에서 'branch > merge...'를 선택하여 merge 할 branch를 선택한다.

 

feature branch는 develop branch와만 merge를 하는 것이 좋기 때문에, feature branch끼리는 merge를 진행하지 않는다.

그렇기 때문에 다른 feature branch의 코드가 필요할 경우,

먼저 develop branch에 merge를 한 후에 이를 개발 진행 중인 feature branch로 merge 한다.

 

+ 개발의 편의를 위해 'Git Graph' extention을 설치한다.

 

 

 

2. Streamlit

 

 

2-1. Button

 

import streamlit as st

st.title("Button")

st.button("Reset", type="primary")
if st.button("Say Hello"):
    st.write("Hello World")
else:
    st.write("Good Bye")

 

 

 

1-2. Download

 

import streamlit as st
import pandas as pd

st.title("Download")

# 데이터 생성
df = pd.DataFrame({
    'first': [1, 2, 3, 4, 5],
    'second': [10, 20, 30, 40, 50]
})

# Dataframe을 csv 파일로 변환
def convert_df_to_cvs(p_df: pd.DataFrame):
    return p_df.to_csv().encode("utf-8")

st.download_button(
    label="Download Data as CSV",
    data=convert_df_to_cvs(df),
    file_name="sample.csv",
    mime="text/csv"
)

# 데이터 출력
st.dataframe(df)

 

 

 

1-3. Form Submit

 

import streamlit as st

st.title("Submit Button")

with st.form(key="my_form"):
    text_input = st.text_input(label="Enter your name")
    submit_button = st.form_submit_button(label="Submit")

st.write("Press submit button to have your name printed below.")

if submit_button:
    st.write(f"Hello {text_input}")

 

 

 

1-4. Link

 

import streamlit as st

st.title("Link Button")

st.link_button(label="Go To Naver", url="https://www.naver.com/")

 

 

 

1-5. Multi Page

 

multi page를 구현하기 위해서 'pages' 폴더를 생성한다.

 

# pages\sub01.py

import streamlit as st

st.title("Sub01 Page")


# pages\sub02.py

import streamlit as st

st.title("Sub02 Page")


# pages\sub03.py

import streamlit as st

st.title("Sub03 Page")

 

import streamlit as st

st.title("Main Page")

 

 

 

1-6. Check Box

 

import streamlit as st

st.title("CheckBox Page")

agree = st.checkbox("I agree.")

if agree:
    st.write("So do I.")

 

 

 

1-7. Toggle

 

import streamlit as st

st.title("Toggle")

toggle = st.toggle("Activate Feature")

if toggle:
    st.write("Feature Activated.")

 

 

 

1-8. Radio

 

import streamlit as st

st.title("Radio")

genre = st.radio(
    "What's your favorite movie genre?",
    ["Comedy", "Drama", "Documentary"],
    captions=["Laugh out loud", "Get the popcorn", "Never stop learning"]
)

if genre == "Comedy":
    st.write("You selected Comedy")
else:
    st.write("You didn't select Comedy")

 

 

 

1-9. Chart

 

1-9-1. Area Chart

import streamlit as st
import pandas as pd
import numpy as np

st.title("Area Chart")

chart_data = pd.DataFrame(
    np.random.randn(20, 3),
    columns=['a', 'b', 'c']
)

st.area_chart(chart_data)

 

 

1-9-2. Bar Chart

import streamlit as st
import pandas as pd
import numpy as np

st.title("Bar Chart")

chart_data = pd.DataFrame(
    np.random.randn(20, 3),
    columns=['a', 'b', 'c']
)

st.bar_chart(chart_data)

 

 

1-9-3. Line Chart

import streamlit as st
import pandas as pd
import numpy as np

st.title("Line Chart")

chart_data = pd.DataFrame(
    {
        'col1': np.random.randn(20),
        'col2': np.random.randn(20),
        'col3': np.random.choice(['A', 'B', 'C'], 20)
    }
)

st.line_chart(chart_data, x="col1", y="col2", color="col3")

 

 

 

 

3. Crawling

 

 

3-0. 가상환경 생성

 

py -3.13 -m venv .venv
.\.venv\Scripts\activate
python -m pip install --upgrade pip
pip install jupyter streamlit pandas requests beautifulsoup4 selenium

 

 

3-1. Web Crawling

 

웹 크롤링은 웹 크롤러/(web crawler)가 정해진 규칙에 따라 여러 개의 웹 페이지를 탐색하는 것을 말한다.

다양한 분야에서 활용이 가능하며, 시장 연구 또는 경쟁사 분석, SNS 트렌드 파악 등에 사용할 수 있다.

그러나 크롤링은 상업적 이용, 개인정보 등의 문제가 되는 부분이 있기 때문에 활용에 유의해야 한다.

또한 DDoS 같은 행위가 나타나지 않도록 하기 위해서 sleep()과 같은 함수를 사용하는 것도 좋다. 

 

3-1-1. Web Crawling 종류

  • 정적(Static) 수집
    • 별도 페이지를 조작할 필요가 없기 때문에 빠르다.
    • 사용 패키지: requests, urllib
    • 파싱 패키지: beautifulsoup
  • 동적(Dynamic) 수집
    • 여러 번의 비동기 통신을 처리하기 때문에 상대적으로 느리다.
    • 사용 패키지: selenium
    • 파싱 패키지: beautifulsoup, selenium

 

3-1-2. 주요 Crawling 모듈

  • requests
    • Python의 HTTP 통신에 사용
  • beautifulsoup
    • HTML, XML, JSON 등 파일의 구문 분석
  • selenium
    • 웹 브라우저를 이용하는 자동화 프로그

 

 

 

4. requests

 

4-1. import requests

 

import requests

 

 

4-2. 웹 페이지 접속

 

url = "https://www.naver.com/"
response = requests.get(url=url)
print(response)				# <Response [200]> -> Status Code: 200 -> OK

 

url = "https://news.naver.com/section/%EC%BD%94%EB%94%A9%EC%A2%8B%EC%95%84"
response = requests.get(url=url)
print(response)				# <Response [404]> -> Status Code: 404 -> Error

 

 

4-3. Headers

 

  • User Agent: 접속한 기기, 운영체제, 브라우저 등에 대한 정보
  • Referer: 요청을 보낸 웹 페이지에 대한 정보
url = "https://n.news.naver.com/mnews/article/005/0001753079"
headers = {
    # 어떤 사람이 어떤 디바이스(PC / Mobile / Tablet / ...)에서 접속했는지에 대한 정보
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36",
    # 현재 표시하는 웹 페이지가 어떤 웹페이지에서 요청되었는지에 대한 정보
    "Referer": "https://news.naer.com/section/105"
}
response = requests.get(url=url, headers=headers)
print(response)

 

 

4-4. Streamlit

 

# common\crawling.py
import requests

def do_crawling() -> str:
    url = "https://n.news.naver.com/mnews/article/009/0005432422"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36",
        "Referer": "https://news.naver.com/section/105"
    }
    response = requests.get(url=url, headers=headers)
    return "Error." if response.status_code >= 400 else "Success."

 

# main.py
import streamlit as st
from common.crawling import do_crawling

st.title("Crawling")

if st.button("Crawling Start"):
    msg = do_crawling()
    st.write(msg)

 

streamlit run main.py

 

 

 

 

5. BeautifulSoup

 

 

5-1. import BeautifulSoup

 

import requests
from bs4 import BeautifulSoup as bs

 

 

5-2. 웹 페이지 접속

 

여기서 response에는 해당 사이트의 문서(.html)가 text 형태로 들어있다.

url = "https://pann.nate.com/talk/350939697"
header = {
    "Referer": "https://pann.nate.com/talk/",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36"
    }

response = requests.get(url=url, headers=header)

if response.status_code >= 400:
    print("Error.")

 

 

5-3. HTML Parser

 

beautiful_text = bs(response.text, "html.parser")
beautiful_text

 

 

5-4. 댓글 가져오기

 

comment_list = beautiful_text.find_all("dd", class_="usertxt")	# list 형태

comment_list[0].get_text().replace("\n", "").strip()

 

 

5-5. Streamlit

 

# common\crawling.py

import requests
from bs4 import BeautifulSoup as bs

def do_crawling():
    url = "https://pann.nate.com/talk/350939697"
    header = {
        "Referer": "https://pann.nate.com/talk/",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36"
        }
    response = requests.get(url=url, headers=header)
    return response

def get_text() -> list:
    response = do_crawling()
    if response.status_code >= 400:
        print("Error.")
        return
    
    beautiful_text = bs(response.text, "html.parser")
    comment_list = beautiful_text.find_all("dd", class_="usertxt")
    return [
        comment.get_text().replace("\n", "").strip() for comment in comment_list
    ]

 

# main.py
import streamlit as st
from common.crawling import get_text

st.title("Crawling")

if st.button("Crawling Start"):
    msg = get_text()
    st.write(msg)

 

streamlit run main.py