1. Jinja

Jinja는 Python에서 사용되는 템플릿 엔진 중 하나로, 템플릿과 데이터를 결합하여 동적인 콘텐츠를 생성하는 데 사용됩니다. 주로 웹 프레임워크에서 HTML 페이지를 동적으로 렌더링하는 데 활용됩니다.

https://jinja.palletsprojects.com/en/3.1.x/

 

2. 설치

Jinja2를 설치합니다.

# Window
pip install jinja2

# macOS
pip3 install jinja2

 

 

3. 간단한 예제

templates라는 디렉토리를 프로젝트 루트에 만들고 그 안에 index.html 파일을 추가합니다.

 

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{ data. title }}</title>
    <link rel="stylesheet" href="/css/style.css">
</head>
<body>
    <h2>안녕! {{ data.name}}</h2>
    <p>{{ request.url }}</p>
</body>
</html>

 

 

main.py 생성 후 작성

from fastapi import FastAPI, Request
from fastapi.templating import Jinja2Templates
from fastapi.staticfiles import StaticFiles
# Jinja2Templates는 html과 연결시켜주는 역할
# 정적파일을 저장해주는 공간을 생성 StaticFiles -> 가상화시켜서 경로를 만들어줌

# http:// http://127.0.0.1:8000/
app = FastAPI()
templates = Jinja2Templates(directory="templates")

app.mount("/css", StaticFiles(directory="static"), name ="css") # 연결 #/css는 가상의 경로가 됨

@app.get("/")
async def read_root(request: Request):
   # 템플릿에 전달할 데이터
    data = {"name": "뚠빵이", "title": "푸바오 당근뺏기"}
    
    # 템플릿 렌더
    return templates.TemplateResponse("index.html", {"request": request, "data": data})

 

 

http://127.0.0.1:8000/에 액세스하면 FastAPI가 Jinja를 사용하여 동적으로 렌더링한 HTML 페이지를 볼 수 있습니다. 위의 예제에서는 index.html 파일에 정의된 변수 {{ name }}과 {{ title }}에 데이터를 전달하여 동적으로 내용을 생성합니다.

 

uvicorn main:app --reload

 

 

4. 로그인 예제

templates라는 디렉토리를 프로젝트 루트에 만들고 그 안에 login.html 파일과 info.html파일을 추가합니다.

 

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>로그인</title>
</head>
<body>
    <h2>로그인</h2>
    <form action="/login" method="post">
        <p>아이디: <input type="text" name="userid"></p>
        <p>비밀번호: <input type="password" name="userpw"></p>
        <p><button type="submit">로그인</button></p>
    </form>
</body>
</html>

 

info.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>회원정보</title>
</head>
<body>
    <h2>회원정보</h2>
    <p>입력한 아이디는 {{ userid }} 이고, 비밀번호는 {{ userpw }} 입니다!</p>
</body>
</html>

 

 

main.py 파일 생성

 

main.py

from fastapi import FastAPI, Request, Form
from fastapi.templating import Jinja2Templates

app = FastAPI()

templates = Jinja2Templates(directory="templates")

@app.get("/login")
async def login_form(request: Request):
    return templates.TemplateResponse("login.html", {"request": request})

@app.post("/login")
async def login(request: Request, userid: str = Form(...), userpw: str = Form(...)):
    return templates.TemplateResponse("info.html", {"request": request, "userid": userid, "userpw": userpw})
#(...)은 무조건 입력해야 하는것 html의 name = useri와 일치해야함

'컴퓨터 비전 > 웹 서비스' 카테고리의 다른 글

FastAPI  (0) 2023.12.16
Streamlit  (2) 2023.12.03
픽사베이  (1) 2023.12.03
인스타그램  (1) 2023.12.03
셀레니움  (0) 2023.12.02

1. Fast API

FastAPI는 Python 기반의 웹 프레임워크로, 주로 API를 빠르게 개발하기 위해 설계되었습니다. FastAPI는 강력한 타입 힌팅(Type Hints)을 활용하여 개발자에게 코드 작성의 안정성과 가독성을 제공합니다.

https://fastapi.tiangolo.com/ko/

 

  타입 힌팅(Type Hints)

타입 힌팅(Type Hints)은 프로그래밍 언어에서 변수, 함수 매개변수, 함수 반환값 등에 대한 데이터 타입 정보를 코드에 명시적으로 제공하는 기술입니다. Python 3.5 이상에서 도입된 기능으로, 코드의 가독성을 높이고 프로그램의 안정성을 강화하는 데 도움이 됩니다.

 

 

2. Fast API vs Flask vs Django

FastApi

장점

FastAPI는 최신 Python 기반 프레임워크로 빠른 성능과 사용하기 쉬운 API로 유명합니다. 비동기 프로그래밍을 지원하므로 실시간 애플리케이션 구축에 적합합니다. 또한 자동 API 문서화 및 유효성 검사를 제공하여 개발자의 시간과 노력을 절약합니다.

단점

FastAPI는 비교적 새로운 프레임워크이며 기존 프레임워크에 비해 커뮤니티 지원 및 리소스가 많지 않을 수 있습니다. 또한 비동기 프로그래밍을 처음 접하는 개발자를 위한 학습 곡선도 있습니다.

활용도

FastAPI는 특히 데이터 집약적인 애플리케이션을 위한 실시간 및 고성능 API 구축에 적합합니다.

 

Django

장점

Django는 웹 애플리케이션 개발에 널리 사용되는 성숙한 Python 기반 프레임워크입니다. 인증, 관리자 패널 및 ORM과 같은 많은 기본 기능을 제공합니다. 또한 지원 및 리소스를 제공하는 크고 활동적인 커뮤니티가 있습니다.

단점

Django는 복잡할 수 있으며 설정하려면 상당한 구성이 필요합니다. 소규모 프로젝트나 경량 API
축에는 적합하지 않을 수도 있습니다.

활용

Django는 웹 애플리케이션, 특히 콘텐츠 기반 웹사이트, 전자상거래 플랫폼 및 소셜 미디어 플랫폼을 구축하는 데 널리 사용됩니다.

 

Flask

장점

Flask는 배우고 사용하기 쉬운 경량 Python 기반 프레임워크입니다. 유연성을 제공하고 개발자가 모듈식 및 확장 가능한 방식으로 웹 애플리케이션을 구축할 수 있도록 합니다. 또한 사용자 정의가 가능하고 소규모 프로젝트를 구축하는 데 적합합니다.

단점

Flask는 다른 프레임워크에 비해 기본 제공 기능이 적기 때문에 개발자가 구현하는 데 더 많은 노력과 시간이 필요할 수 있습니다. 또한 대규모 웹 애플리케이션을 구축하는 데 적합하지 않을 수도 있습니다.

활용

Flask는 개인 웹 사이트, 간단한 API 및 내부 대시보드와 같은 소규모 웹 애플리케이션 및 프로토타입을 구축하는 데 적합합니다.

 

요약

FastAPI는 실시간 및 고성능 API를 구축하는 데 적합한 현대적이고 빠른 프레임워크이고, Django는 복잡한 웹 애플리케이션을 구축하는 데 적합한 성숙한 프레임워크이며, Flask는 소규모 웹 애플리케이션 및 프로토타입을 구축하는 데 적합한 가볍고 유연한 프레임워크입니다. . 그들 사이의 선택은 개발 팀의 기술과 경험뿐만 아니라 프로젝트의 특정 요구 사항과 요구 사항에 따라 다릅니다.

 

3. 설치

FastAPI를 설치하기 전에 Python 가상환경을 만들어줍니다. 가상환경을 사용하면 프로젝트 간에 의존성 충돌을 방지하고 프로젝트 별로 필요한 패키지를 독립적으로 관리할 수 있습니다.

# Windows
python -m venv venv

# macOS/Linux
python3 -m venv venv

 

 

가상환경이 생성되면 해당 가상환경을 활성화합니다.

# Windows
venv\Scripts\activate

# macOS/Linux
source venv/bin/activate

 

 

FastAPI를 사용하려면 먼저 FastAPI 패키지를 설치해야 합니다.

pip install fastapi

 

 

FastAPI 애플리케이션을 실행하기 위해 uvicorn이라는 ASGI 서버가 필요합니다.

pip install "uvicorn[standard]"

 

 

uvicorn[standard]

1. 이 패키지는 uvicorn에 기본적으로 포함된 기능 외에도 추가적인 표준 미들웨어를 포함합니다.

2. 표준 미들웨어는 보안, 로깅 및 기타 서버 관련 기능을 추가하는 데 도움이 됩니다.

3. 예를 들어, Gzip 압축, CORS(Cross-Origin Resource Sharing) 지원 등이 기본적으로 포함되어 있습니다.

 

uvicorn

1. 기본적으로 필요한 최소한의 기능만을 제공하는 패키지입니다.

2. uvicorn[standard]에 비해 미들웨어가 적고, 기본적인 서버 기능만을 제공합니다.

 

 

※ ASGI 서버

ASGI는 Asynchronous Server Gateway Interface의 약자로, 비동기 웹 애플리케이션과 서버 간의 표준 인터페이스를 제공하는 프로토콜입니다. ASGI는 Python 웹 애플리케이션을 구축할 때 비동기 처리를 지원하고, 실시간 기능을 구현할 수 있도록 하는 중간 계층 역할을 합니다.

기존의 WSGI(웹 서버 게이트웨이 인터페이스)는 동기적인 요청과 응답을 다루는 데에 효과적이었습니다. 하지만 현대의 웹 애플리케이션에서는 동시성(concurrency)이나 비동기(asynchronous) 처리가 중요한 역할을 하게 되면서 WSGI의 한계가 드러나게 되었습니다.

 

 

 

4. 기본 예제

main.py

from fastapi import FastAPI

users = {
    0: {"userid": "apple", "name": "푸바오"},
    1: {"userid": "banana", "name": "아이바오"},
    2: {"userid": "orange", "name": "러바오"}
}

app = FastAPI()

# http://127.0.0.1:8000/users/0
# uvicorn main:app --reload
@app.get("/users/{id}")
def find_user(id: int):
    user = users[id]
    return user

# http://127.0.0.1:8000/users/0/userid
# http://127.0.0.1:8000/docs
@app.get("/users/{id}/{key}")
def find_user_by_key(id: int, key: str):
    user = users[id][key]
    return user

 

 

5. 실행

작성한 FastAPI 애플리케이션을 실행합니다. 다음 명령을 사용하여 uvicorn을 통해 실행할 수 있습니다.

uvicorn main:app --reload

 

FastAPI는 자동으로 생성된 Swagger UI를 통해 API 문서를 제공합니다. 기본적으로 http://127.0.0.1:8000/docs 또는 http://127.0.0.1:8000/redoc에서 확인할 수 있습니다. Swagger UI를 통해 API의 엔드포인트, 매개변수, 응답 형식 등을 살펴볼 수 있습니다.

 

 

6. REST와 RESTful API

REST: "Representational State Transfer" 약자로,  상에서 자원을 표현하고 상태를 전송하기 위한 아키텍처적인 스타일입니다. REST 네트워크 아키텍처의  형식으로, 리소스(자원) 정의하고 이를 고유하게 식별하는  중점을 두며, HTTP 프로토콜을 기반으로 하고 있습니다. REST 간결하고 확장 가능한 디자인을 지향하여  서비스를 위한 표준 아키텍처로 널리 사용되고 있습니다.

 

RESTful API(REST API): REST 아키텍처를 따르는  서비스의 인터페이스를 말합니다.  API 클라이언트와 서버 간의 통신을 위한 규칙을 제공하며, 자원의 생성, 조회, 수정, 삭제(CRUD) 같은 기본적인 데이터 조작을 위한 메서드를 제공합니다. RESTful API HTTP 기반으로 하기 때문에 웹에서 쉽게 사용할  있습니다. 클라이언트와 서버 간의 통신은 자원의 표현을 통해 이루어지며 표현은 일반적으로 JSON 또는 XML 형식으로 이루어집니다.

 

예를 들어, 다음은 간단한 RESTful API의 예시입니다:

자원(리소스): /users

HTTP 메서드: GET (모든 사용자 조회), POST (새로운 사용자 생성), PUT 또는 PATCH (사용자 정보 업데이트), DELETE (사용자 삭제)

 

 

7. JSON

JSON은 "JavaScript Object Notation" 약어로, 데이터를 표현하고 교환하기 위한 경량의 데이터 형식입니다. 주로 서버와 클라이언트 간에 데이터를 주고 받을  사용되며, 텍스트 형태로 이루어져 있습니다. JSON은 간결하면서도 읽기 쉽고 파싱하기 쉬운 구조를 가지고 있어 많은 프로그래밍 언어에서 지원하고 있습니다.

{
  "키1": "값1",
  "키2": "값2",
  "키3": {
    "키4": "값4",
    "키5": "값5"
  },
  "배열키": [
    "배열값1",
    "배열값2",
    "배열값3"
  ]
}

 

 

8. HTTP Method

FastAPI에서는  메서드에 대응하는 데코레이터를 제공하여 해당 엔드포인트에 대한 핸들러 함수를 등록할  있습니다. 이러한 데코레이터를 사용하여 각각의 HTTP 메서드에 대한 동작을 정의할  있습니다.

from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional

users = {
    0: {"userid": "apple", "name": "푸바오"},
    1: {"userid": "banana", "name": "아이바오"},
    2: {"userid": "orange", "name": "러바오"}
}

app = FastAPI()
# http://127.0.0.1:8000/user/?
@app.get("/users/{id}")
def find_user(id: int):
    item = users[id]
    return item

# http://127.0.0.1:8000/users/0/userid
@app.get("/users/{id}/{key}")
def find_user_by_key(id:int, key:str):
    user = users[id][key]
    return user

# http://127.0.0.1:8000/id-by-name?name=푸바오
@app.get("/id-by-name")
def find_user_by_name(name:str):
    for userid, user in users.items():
        if user['name'] == name:
            return user
    return {"error : 데이터를 찾지 못함"}

class User(BaseModel):
    userid : str
    name : str

@app.post("/{id}")
def create_user(id: int, user: User):
    if id in users:
        return {"error" : "이미 존재하는 키"}
    users[id] = user.__dict__       # user객체를 딕셔너리로 만듬
    return {"success" : "ok"}


class UserForUpdate(BaseModel):
    userid: Optional[str]
    name: Optional[str]

@app.put("/{id}")
def update_user(id:int, user: UserForUpdate):
    if id not in users:
        return {"error" : "id가 존재하지 않음"}
    if user.userid : 
        users[id]['userid'] = user.userid
    if user.name:
        users[id]['name'] = user.name
    return {"success" : "ok"}

@app.delete("/users/{id}")
def delete_item(id:int):
    users.pop(id)
    return {"success": "ok"}

'컴퓨터 비전 > 웹 서비스' 카테고리의 다른 글

Jinja 템플릿 엔진  (0) 2023.12.18
Streamlit  (2) 2023.12.03
픽사베이  (1) 2023.12.03
인스타그램  (1) 2023.12.03
셀레니움  (0) 2023.12.02

Streamlit

  • 파이썬으로 데이터 분석을 위한 웹앱을 쉽게 개발할 수 있게 도와주는 라이브러리
  • https://streamlit.io/

 

# 설치

# window
pip install streamlit

# mac
pip3 install streamlit

 

 

# 설치 확인 및 데모 확인

streamlit hello

 

 

#실행

- 터미널에서 입력

streamlit run 파일명

 

 

 

 

import streamlit as st

st.title('hi streamlit')
st.write('텍스트 구간')

'''
# 여기는 제목입니다.
### 여기는 작은 제목입니다.
- 첫번째 요소
- 두번째 요소
- 세번째 요소
'''

text = st.text_input('여기에 입력')
st.write(text)

selected = st.checkbox('개인정보 사용에 동의하시겠습니까?')
if selected:
    st.success('동의했습니다')

market = st.selectbox('시장',('코스닥','코스피','나스닥'))
st.write(f'선택된 market : {market}')

options = st.multiselect('종목',['카카오', '네이버','삼성','엘지'])
st.write(','.join(options))

st.metric(label='카카오', value= '40,000원', delta= '-1,000원')

 

# 실행 화면

 

'컴퓨터 비전 > 웹 서비스' 카테고리의 다른 글

Jinja 템플릿 엔진  (0) 2023.12.18
FastAPI  (0) 2023.12.16
픽사베이  (1) 2023.12.03
인스타그램  (1) 2023.12.03
셀레니움  (0) 2023.12.02

1. 이미지 수집하기

* [픽사베이](https://pixabay.com/ko/)

 

import chromedriver_autoinstaller
import time
from selenium import webdriver
from urllib.request import Request, urlopen
import ssl
ssl._create_default_https_context = ssl._create_unverified_context


driver = webdriver.Chrome()
url = 'https://pixabay.com/ko/images/search/음식/'
driver.get(url)

 

 

# 이미지가 있는 주소창 xpath
image_area_xpath = '/html/body/div[1]/div[1]/div/div[2]/div[3]/div'

# 예시용 하나의 이미지 xpath
image_xpath = '/html/body/div[1]/div[1]/div/div[2]/div[3]/div/div/div[1]/div[1]/div/a/img'

 

# 예시용 하나의 이미지 url가져오기

image_url = driver.find_element('xpath',image_xpath).get_attribute('src')
print('image_url:', image_url)

 

# 예시용 하나의 이미지를 나의 컴퓨터 파일안에 저장하기

- 사진을 pic.jpg 라는 이름으로 저장

image_byte = Request(image_url, headers={'User-Agent':'Mozilla/5.0 (X11; Linux x86_64)'})
f = open('pic.jpg','wb') # w: write, r: read, a: append, b: binary, t: text
f.write(urlopen(image_byte).read()) 
f.close()

 

 

 

2. 여러개 이미지 수집하기

 

from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
url = 'https://pixabay.com/ko/images/search/음식/'
driver.get(url)
time.sleep(3)


image_area_xpath = '/html/body/div[1]/div[1]/div/div[2]/div[3]/div'
image_area = driver.find_element(By.XPATH, image_area_xpath)
image_elements = image_area.find_elements(By.TAG_NAME, 'img')

image_urls = [] #내용을 담을 빈 리스트

for image_element in image_elements:
    image_url = image_element.get_attribute('data-lazy-src')
    if image_url is None: # 주소가 없을시 src로 주소 뽑기
        image_url = image_element.get_attribute('src')
    print(image_url)
    image_urls.append(image_url) # image_urls 리스트에 주소 추가

 

from urllib import parse
import os

for i in range(len(image_urls)):
    image_url = image_urls[i]
    url = parse.urlparse(image_url) # 이미지 경로를 가져옴 / parse: 접속해서 데이터를 가져온후 저장까지 해줌 
    name, ext = os.path.splitext(url.path) #파일이름, 확장명

    image_byte = Request(image_url, headers={'User-Agent':'Mozilla/5.0 (X11; Linux x86_64)'})
    f = open(f'pic{i}.jpg','wb') # w: write, r: read, a: append, b: binary, t: text
    f.write(urlopen(image_byte).read()) 
    f.close()

 

 

 

3. 함수로 리팩토링

  • crawl_and_save_image(keyword, pages)
  • os.mkdir('음식') /open('음식/파일이름.jpg', 'wb')

 

def crawl_and_save_image(keyword, pages):
    image_urls = []
    for i in range(1, pages+1):
        url = f'https://pixabay.com/ko/images/search/{keyword}/?pagi={i}'
        # print(url)
        
        driver.get(url)
        time.sleep(3)
        image_area_xpath = '/html/body/div[1]/div[1]/div/div[2]/div[3]/div'
        image_area = driver.find_element(By.XPATH, image_area_xpath)
        image_elements = image_area.find_elements(By.TAG_NAME, 'img')
        
        for image_element in image_elements:
            image_url = image_element.get_attribute('data-lazy-src')
            if image_url is None:
                image_url = image_element.get_attribute('src')
            print(image_url)
            image_urls.append(image_url)
    
    
    if not os.path.exists(keyword):
        os.mkdir(keyword)
    
    
    for i in range(len(image_urls)):
        image_url = image_urls[i]
        
        # https://cdn.pixabay.com/photo/2016/12/26/17/28/spaghetti-1932466_1280.jpg
        filename = image_url.split('/')[-1]
        image_byte = Request(image_url, headers={'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko)'})
        f = open(f'{keyword}/{filename}', 'wb')
        f.write(urlopen(image_byte).read())
        f.close()
driver = webdriver.Chrome()
crawl_and_save_image('음식', 2)

'컴퓨터 비전 > 웹 서비스' 카테고리의 다른 글

FastAPI  (0) 2023.12.16
Streamlit  (2) 2023.12.03
인스타그램  (1) 2023.12.03
셀레니움  (0) 2023.12.02
크롤링(Crawling)  (0) 2023.12.02

1. 로그인

# 크롬창으로 인스타그램 홈 들어가기

import chromedriver_autoinstaller
from selenium import webdriver

driver = webdriver.Chrome()

url = 'http://www.instagram.com/'
driver.get(url)

 

# 아이디 비밀번호 입력후 로그인

#인스타로그인
id = '<나의 아이디>'
pw = '<나의 비밀번호>'


#아이디/비밀번호 칸 copy full xpath/  
input_id = driver.find_element('xpath', '/html/body/div[2]/div/div/div[2]/div/div/div/div[1]/section/main/article/div[2]/div[1]/div[2]/form/div/div[1]/div/label/input')
input_pw = driver.find_element('xpath', '/html/body/div[2]/div/div/div[2]/div/div/div/div[1]/section/main/article/div[2]/div[1]/div[2]/form/div/div[2]/div/label/input')


input_id.send_keys(id)
input_pw.send_keys(pw)

# 로그인 버튼 클릭
driver.find_element('xpath','/html/body/div[2]/div/div/div[2]/div/div/div/div[1]/section/main/article/div[2]/div[1]/div[2]/form/div/div[3]').click()

 

 

2. 해시태그 검색

# 검색할 해시태그 'ootd'

 

hashtag = 'ootd'
url = f'https://www.instagram.com/explore/tags/{hashtag}/'
driver.get(url)

 

 

3. 스크롤 내리기

import time

for _ in range(1): #스크롤을 한번만 내림
    driver.execute_script('window.scrollTo(0, document.body.scrollHeight)') 
    # 안에 자바스크립트 문법을 쓸 수 있다. 0부터 끝까지 스크롤 이동
    #time.sleep(3) #3초 쉬고 스크롤내리기

 

 

4. 원하는 사진 클릭하기

pic = '/html/body/div[2]/div/div/div[2]/div/div/div/div[1]/div[1]/div[2]/section/main/article/div/div/div/div[1]/div[3]/a'
driver.find_element('xpath',pic).click()

 

 

5. 좋아요 클릭

like = '/html/body/div[8]/div[1]/div/div[3]/div/div/div/div/div[2]/div/article/div/div[2]/div/div/div[2]/section[1]/span[1]/div'
driver.find_element('xpath', like).click()

 

 

6. 댓글달기

comment = '/html/body/div[8]/div[1]/div/div[3]/div/div/div/div/div[2]/div/article/div/div[2]/div/div/div[2]/section[3]/div/form/div/textarea'
msg = '★'
driver.find_element('xpath', comment).click()
driver.find_element('xpath', comment).send_keys(msg)

btn = '/html/body/div[8]/div[1]/div/div[3]/div/div/div/div/div[2]/div/article/div/div[2]/div/div/div[2]/section[3]/div/form/div/div[2]/div'
driver.find_element('xpath',btn).click()

'컴퓨터 비전 > 웹 서비스' 카테고리의 다른 글

FastAPI  (0) 2023.12.16
Streamlit  (2) 2023.12.03
픽사베이  (1) 2023.12.03
셀레니움  (0) 2023.12.02
크롤링(Crawling)  (0) 2023.12.02

# Jupyter Notebook 주요 단축키
* Enter: 일반 모드에서 편집 모드로 전환
* ESC: 편집 모드에서 일반 모드로 전환

 

* ▶︎일반 모드 단축키
  * A: 선택된 셀 위에 새로운 셀 추가
  * B: 선택된 셀 아래에 새로운 셀 추가
  * X: 선택된 셀 잘라내기
  * C: 선택된 셀 복사
  * V: 선택된 셀 아래에 붙여넣기
  * D, D: 선택된 셀 삭제
  * Z: 셀 삭제 취소

* ▶︎편집 모드 단축키
  * Ctrl + Z: 되돌리기
  * Ctrl + Y: 되돌리기 취소
  * Ctrl + A: 셀 내용 전체 선택
  * Ctrl + Home: 셀 맨 위로 이동
  * Ctrl + End : 셀 맨 아래로 이동
  * Ctrl + D: 현재 줄 삭제
  * Tab: 자동 완성 기능 사용

 

1. 셀레니움

  • 셀레니움은 브라우저를 컨트롤 할 수 있도록 지원하는 라이브러리

 

# 셀레니움 설치

# window
!pip install selenium

# mac
!pip3 install selenium

 

# 크롬 드라이버 설치

# window
!pip install chromedriver_autoinstaller

# mac
!pip3 install chromedriver_autoinstaller
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome() #창 띄우기
driver.get('http://www.google.com') #구글이동
search = driver.find_element('name', 'q') # find_element: 태그에서 하나 찾기 :name에서 q만 찾기
search.send_keys('날씨') # 검색창에 날씨 입력
search.send_keys(Keys.RETURN) # 검색

 

 

2. 네이버 웹툰

네이버웹툰 베스트댓글과 전체댓글 크롤링하기

  • https://comic.naver.com/webtoon/detail?titleId=641253&no=471&week=fri
driver = webdriver.Chrome() #창 띄우기
driver.get('https://comic.naver.com/webtoon/detail?titleId=641253&no=471&week=fri') # 네이버 웹툰으로 이동
!pip3 install bs4

 

# 베스트 댓글 크롤링하기

from bs4 import BeautifulSoup
soup = BeautifulSoup(driver.page_source)
comment_area = soup.findAll('span', {'class':'u_cbox_contents'})
print(comment_area)
print('********베스트 댓글*****************')
for i in range(len(comment_area)):
    comment = comment_area[i].text.strip() # 텍스트만 뽑고 공백삭제
    print(comment)
    print('-' * 30)

 

 

# 전체댓글 크롤링하기

 

  • Xpath: 기존의 컴퓨터 파일 시스템에서 사용하는 경로 표현식과 유사한 경로 언어
  • Copy full Xpath
  • 크롤링을 원하는 위치를 클릭후 우클릭으로 개발자모드(F12/option+control+I) -> Copy -> Copy full Xpath로 경로복사
  • /html/body/div[1]/div[5]/div/div/div[5]/div[1]/div[3]/div/div/div[4]/div[1]/div/ul/li[2]/a/span[2]
driver.find_element('xpath','/html/body/div[1]/div[5]/div/div/div[5]/div[1]/div[3]/div/div/div[4]/div[1]/div/ul/li[2]/a/span[2]').click
soup = BeautifulSoup(driver.page_source)

commentall_area = soup.findAll('span', {'class':'u_cbox_contents'})
print(commentall_area)
print('********전체 댓글*****************')
for i in range(len(commentall_area)):
    comment = commentall_area[i].text.strip() # 텍스트만 뽑고 공백삭제
    print(comment)
    print('-' * 30)

'컴퓨터 비전 > 웹 서비스' 카테고리의 다른 글

FastAPI  (0) 2023.12.16
Streamlit  (2) 2023.12.03
픽사베이  (1) 2023.12.03
인스타그램  (1) 2023.12.03
크롤링(Crawling)  (0) 2023.12.02

1. 크롤링과 스크레이핑

- 크롤링(Crawling) : 인터넷의 데이터를 확용하기 위해 인터넷의 정보들을 수집하는 행위

- 스크레이핑(Scraping): 크롤링 + 데이터를 추출하고 가공하는 행위

 

2. Basig English Speaking

import requests
from bs4 import BeautifulSoup

site = 'https://basicenglishspeaking.com/daily-english-conversation-topics/'
request = requests.get(site) # 리퀘스트를 get방식으로 접속
print(request) #[200] 정상적인 접속

output

더보기

<Response [200]>  #정상적인 접속

print(request.text) #가져온 html 확인
soup = BeautifulSoup(request.text)

# div의 딱 한부분만 가져옴
divs = soup.find('div', {'class':'thrv-columns'})
print(divs)

# div안에 있는 앵커('a')태그만 찾기
links = divs.findAll('a')
print(links)

# 리스트이기 때문에 for문으로 돌면서 텍스트만 찍기
# 앵커태그 안에 있는 텍스트만 가져오기
for link in links:
    print(link.text)

output

더보기

Family
Restaurant
Books
...
Handcraft Items
Plastic Surgery
Success

 

subject = []

for link in links: # (links)에서 앵커태그를 하나씩 링크(link)로 뽑아 빈 리스트에 텍스트가 하나씩 들어감
    subject.append(link.text)
len(subject)

output

print('총', len(subject), '개의 주제를 찾았습니다.')
for i in range(len(subject)):
    print('{0:2d}, {1:s}'.format(i+1, subject[i]))

 

output

더보기

총 75 개의 주제를 찾았습니다.
1. Family
2. Restaurant
3. Books
...
73. Handcraft Items
74. Plastic Surgery
75. Success

3. 다음 뉴스기사

# 제목을 뽑아보는 크롤링

 

크롤링할 기사
#https://v.daum.net/v/20231124152902275

def daum_news_title(news_id):
    url = 'https://v.daum.net/v/{}'.format(news_id)
    request = requests.get(url)
    soup = BeautifulSoup(request.text)
    title = soup.find('h3', {'class':'tit_view'}) # class안 tit_view 찾기

    if title:
        return title.text.strip()
    return '제목없음'

 

 

daum_news_title('20231124152902275')

output

더보기

' 김유정 "이상이와 1년간 매일같이 보고 있어, 어색할까 걱정" (\'마이 데몬\') '

daum_news_title('20231124144808698')

output

더보기

'한효주, 美에미상 빛냈다..'큰칼' 잊게 만든 우아美+유창한 영어 [종합]'

 

 

 

 

 

 

4. 벅스 뮤직차트

벅스차트
# https://music.bugs.co.kr/chart


request = requests.get('https://music.bugs.co.kr/chart')
soup = BeautifulSoup(request.text)

titles = soup.findAll('p', {'class':'title'}) # findAll : 선택한 항목의 모든요소 찾기
#print(titles)
artists = soup.findAll('p',{'class':'artist'})
#print(artists)

for i, (t, a) in enumerate(zip(titles, artists)):
    title = t.text.strip().replace('[19금]\n', '') # replace -> 19금 -> ''변경
    artist = a.text.strip().split('\n')[0] # 스플릿으로 문자열을 나눈 후 공백을 삭제후 첫번째 요소만 출력
    print('{0:3d}위 {1} - {2}'.format(i+1, artist, title))

 

# enumerate :  반복문을 사용할 때 인덱스와 값을 함께 가져오기 위해 사용되는 내장 함수
# zip 함수 :  zip() 함수는 파이썬에서 여러 개의 반복 가능한(iterable) 객체를 병렬적으로 묶어주는 내장 함수

 

output

더보기

1위 ATEEZ(에이티즈) - 미친 폼 (Crazy Form)
2위 태연 (TAEYEON) - To. X
3위 LE SSERAFIM (르세라핌) - Perfect Night
...
98위 탑현 - 나에게 그대만이
99위 케이시 - 사실말야내가말야그게그러니까말이야
100위 KISS OF LIFE - Sugarcoat (NATTY Solo)

 

 

 

 

5. 멜론차트

  • robots.txt : 웹 사이트에 크롤러같은 로봇들의 접근을 제어하기 위한 규약 (권고안이라 꼭 지킬 의무는 없음) (https://www.melon.com/robots.txt)
멜론차트
#https://www.melon.com/chart/index.htm

request = requests.get('https://www.melon.com/chart/index.html')
print(request)
output
<Response [406]> #406번은 정보를 가져오지 못한 것

 

titles = soup.findAll('div class',{'class' : 'title'})
print(titles)
ouput
[] 

 

 

 

이럴땐 User-Agent가 필요

User-Agent

# User-Agent
# Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36
header = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)'}
request = requests.get('https://www.melon.com/chart/index.html',headers=header)
print(request)
output
<Response [200]>

 

 

titles = soup.findAll('div',{'class':'rank01'})
#print(titles)
artists = soup.findAll('span',{'class':'checkEllipsis'})
#print(artists)

for i, (t, a) in enumerate(zip(titles, artists)):
    title = t.text.strip().replace('19금\n','')#split('\n')
    artist = a.text.strip()
    print('{0:3d}위 {1} - {2}'.format(i+1, artist, title))
output
1위 LE SSERAFIM (르세라핌) - Perfect Night
2위 aespa - Drama
3위 IVE (아이브) - Baddie
...
98위 최유리 - 숲
99위 케이시 (Kassy) - 사실말야내가말야그게그러니까말이야
100위 BE'O (비오) - 미쳐버리겠다 (MAD)

 

 

 

 

6. 네이버증권

 
# 이름, 가격, 종목코드, 거래량
# 그린리소스, (가격 : 52,300, 종목코드 : 402490, 거래량 : 34,192,513))
# {'name':'그린리소스, 'price':52300, code: '402490', 'volume': 34192513}

 

request = requests.get('https://finance.naver.com/item/main.naver?code=402490')
soup = BeautifulSoup(request.text)

# 이름
div_totalinfo = soup.find('div', {'class':'new_totalinfo'})
name = div_totalinfo.find('h2').text

# 가격
div_today = div_totalinfo.find('div', {'class':'today'})
em = div_today.find('em')
price = div_today.find('span',{'class':'blind'}).text

# 종목코드
div_code = div_totalinfo.find('div', {'class':'description'})
code = div_code.find('span',{'class':'code'}).text

# 거래량
table_no_info = soup.find('table',{'class','no_info'})
tds = table_no_info.findAll('td')
volume = tds[2].find('span',{'class':'blind'}).text

# 딕셔너리
dic = {'name': name, 'code':code, 'price':price, 'volume':volume}
print(dic)

 

 

네이버증권 종목코드로 정보추출하는 함수

 

def naver_finance(code):
    # 코드
    site = f'https://finance.naver.com/item/main.naver?code={code}'
    request = requests.get(site)
    soup = BeautifulSoup(request.text)

    # 이름
    div_totalinfo = soup.find('div', {'class':'new_totalinfo'})
    name = div_totalinfo.find('h2').text

    # 가격
    div_today = div_totalinfo.find('div', {'class':'today'})
    em = div_today.find('em')
    price = em.find('span', {'class':'blind'}).text

    # 거래량
    table_no_info = soup.find('table', {'class':'no_info'})
    tds = table_no_info.findAll('td')
    volume = tds[2].find('span', {'class':'blind'}).text

    dic = {'name':name, 'code':code, 'price':price, 'volume':volume}
    return dic

 

naver_finance('252670')
output
{'name': 'KODEX 200선물인버스2X',
'code': '252670',
'price': '2,580',
volume': '79,577,748'}

 

naver_finance('032790')
output
{'name': '엠젠솔루션',
'code': '032790',
'price': '1,928',
'volume': '692,851'}

 

codes = ['017040', '007980', '352090', '402490', '032790']
data = []
for code in codes:
    dic = naver_finance(code)
    data.append(dic)
print(data)
output
[{'name': '광명전기', 'code': '017040', 'price': '2,430', 'volume': '757,418'}, {'name': '태평양물산', 'code': '007980', 'price': '2,985', 'volume': '3,630,259'}, {'name': '스톰테크', 'code': '352090', 'price': '12,510', 'volume': '803,272'}, {'name': '그린리소스', 'code': '402490', 'price': '34,750', 'volume': '1,371,371'}, {'name': '엠젠솔루션', 'code': '032790', 'price': '1,928', 'volume': '692,851'}]

 

 

 

# 데이터프레임 생성

# pandas: 데이터를 2차원으로 바꿔주는 기능

import pandas as pd
df = pd.DataFrame(data)
df
output

 

# 자료를 엑셀로 변환

df.to_excel('naver_finace.xlsx') # 자료 -> 엑셀 변환

 

 

 

 

# 지니뮤직
# https://www.genie.co.kr/
# ...
# import time을 이용
# time.sleep(3)
# 지니차트 1 ~ 200위까지 크롤링해서 엑셀로 만들기
import time
import requests
import pandas as pd
from bs4 import BeautifulSoup

# 상위 200위까지 출력
data = []
for j in range(1, 5):  # 페이지는 1에서 4까지
    header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'}
    request = requests.get(f'https://www.genie.co.kr/chart/top200?ditc=D&ymd=20231124&hh=21&rtm=Y&pg={j}', headers=header)
    soup = BeautifulSoup(request.text)

    table = soup.find('table', {'class': 'list-wrap'})
    titles = table.findAll('a', {'class': 'title ellipsis'})
    artist = table.findAll('a', {'class': 'artist ellipsis'})
    number = soup.findAll('td', {'class': 'number'})

    for i, (n, t, a) in enumerate(zip(number, titles, artist)):
        numbers = n.text.strip().split('\n')[0]
        titles = t.text.strip().replace('19금', '').lstrip()  # 19금 아이콘 제거
        artists = a.text.strip()
        dic =('{0}위 {1} - {2}'.format(numbers, artists, titles))
        data.append(dic)
    time.sleep(2)

 

df = pd.DataFrame(data)
df

 

output

 

 

df.to_excel('지니.xlsx')
지니.xlsx 파일

 

 

 

'컴퓨터 비전 > 웹 서비스' 카테고리의 다른 글

FastAPI  (0) 2023.12.16
Streamlit  (2) 2023.12.03
픽사베이  (1) 2023.12.03
인스타그램  (1) 2023.12.03
셀레니움  (0) 2023.12.02