OkBublewrap

N배 빠른 크롤링(1) 본문

Python/학습용

N배 빠른 크롤링(1)

옥뽁뽁 2025. 2. 23. 00:23

시스템 정보 확인

platform
실행하고자하는 프로그램이 시스템 요구사항을 만족하는지 사양 정보를 확인할 때 사용하는 모듈

 

 

운영 체제 확인

def printOsInfo():
    print('OS                   :\t', platform.system())
    print('OS Version           :\t', platform.version())
    
    
printOsInfo()

 

OS                   :  Windows
OS Version           :  10.0.19045

 

 

CPU / 메모리 확인

# 튜플 객체형으로 확인
info = platform.uname()
# CPU
info.processor
# 'Intel64 Family 6 Model 94 Stepping 3, GenuineIntel'

 

# CPU 코어 개수 확인
import os
os.cpu_count()
import platform , psutil
 
def printSystemInfor():
    print('Process information  :\t', platform.processor())
    print('Process Architecture :\t', platform.machine())
    print('CPU Cores          :\t', os.cpu_count())
    print('RAM Size             :\t',str(round(psutil.virtual_memory().total / (1024.0 **3)))+"(GB)")
    printSystemInfor()

 

Process information  :  Intel64 Family 6 Model 94 Stepping 3, GenuineIntel
Process Architecture :  AMD64
CPU Cores          :  4
RAM Size             :  8(GB)

 

argparse 실습

from __future__ import print_function
import argparse

def main():
    parser = argparse.ArgumentParser(description='This code is written for practice about argparse')
    parser.add_argument('X', type=float,
                        metavar='First_number',
                        help='첫번째 숫자는?')
    parser.add_argument('Y', type=float,
                        metavar='Second_number',
                        help='두번째 숫자는?')
    parser.add_argument('--op', type=str, default='덧셈',
                        choices=['덧셈', '뺄셈', '곱하기', '나누기'],
                        help='연산 방법을 선택해 주세요')
    args = parser.parse_args()

    X = args.X
    Y = args.Y
    op = args.op
    print(calc(X, Y, op))


def calc(x, y, op):
    if op == '덧셈':
        return x + y
    elif op == '뺄셈':
        return x - y
    elif op == '곱하기':
        return x * y
    elif op == '나누기':
        return x / y


if __name__ == "__main__":
    main()

 

1️⃣ argparse 라이브러리 활용

parser = argparse.ArgumentParser(description='This code is written for practice about argparse')
  • argparse.ArgumentParser() → 명령줄 인자를 해석하는 객체를 생성
  • description → 프로그램에 대한 설명을 추가

 

2️⃣ 숫자 두 개 입력받기

parser.add_argument('X', type=float, metavar='First_number', help='첫번째 숫자는?')
parser.add_argument('Y', type=float, metavar='Second_number', help='두번째 숫자는?')
  • X와 Y라는 위치 인자(필수 입력값)를 float 타입으로 입력받음.
  • metavar → 도움말에 표시될 변수명
  • help → 설명 추가

 

실행 예시

python script.py 3 5

 

3️⃣ 연산 방법 선택 (--op)

parser.add_argument('--op', type=str, default='덧셈',
                    choices=['덧셈', '뺄셈', '곱하기', '나누기'],
                    help='연산 방법을 선택해 주세요')

 

  • --op → 선택적 인자 (옵션)
  • default='덧셈' → 기본값은 '덧셈'
  • choices → '덧셈', '뺄셈', '곱하기', '나누기' 중 하나만 가능

 

실행 예시

python script.py 3 5 --op 곱하기

 

4️⃣ 연산 수행 (calc 함수)

def calc(x, y, op):
    if op == '덧셈':
        return x + y
    elif op == '뺄셈':
        return x - y
    elif op == '곱하기':
        return x * y
    elif op == '나누기':
        return x / y
  • 입력된 op에 따라 해당 연산을 수행
  • 덧셈, 뺄셈, 곱하기, 나누기 중 하나를 수행하고 결과를 반환

 

5️⃣ main() 함수 실행

실행 예제

 

실행 로그 남기기

logging

  • 프로그램이 실행되는 동안 일어나는 정보를 기록하고 관리하는 로깅 모듈
  • 로그는 파일뿐만 아니라 소켓, 이메일, 콘솔 등 다양한 방법으로 출력이 가능
  • print()와 차이점?
    • 콘솔창에 문자열을 출력하는 print 문을 사용해서 기록을 남기는 방법도 있지만, 실행 기록을 관리하거나 분석 시에는 활용이 어려움
    • logging은 프로그램 진행 상황에 따라 로그를 레벨 별로 관리하거나 모듈 별 별도의 기록을 남기는 등의 작업이 가능

 

로그 레벨 5단계

로그는 설정한 레벨 이상만 출력

예를 들어 핸들러나 로거의 로그 레벨을 INFO로 설정하면 DEBUG 로그는 출력되지 않고 INFO 이상의 로그만 출력

 

DEBUG < INFO < WARNING < ERROR < CRITICAL

 

  • 1단계 DEBUG : 디버깅 목적으로 사용
  • 2단계 INFO : 일반 정보를 출력할 목적으로 사용
  • 3단계 WARNING : 경고 정보를 출력할 목적으로(작은 문제) 사용
  • 4단계 ERROR : 오류 정보를 출력할 목적으로(큰 문제) 사용
  • 5단계 CRITICAL : 아주 심각한 문제를 출력할 목적으로 사용

 

import logging

# 로그 생성
logger = logging.getLogger()

# 로그의 출력 기준 설정
logger.setLevel(logging.WARNING)

# log 형식 지정
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# log 출력
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)
logger.addHandler(stream_handler)

# log 파일 생성
file_handler = logging.FileHandler('sample2.log')
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)

def myfunc():
    logger.debug("DEBUG 로그입니다.")
    logger.info("INFO 로그입니다.")
    logger.warning("WARNING 로그입니다.")
    logger.error("ERROR 로그입니다.")
    logger.critical("CRITICAL 로그입니다.")

myfunc()

 

1️⃣ logging.getLogger() (로그 객체 생성)

  • 로그를 기록할 수 있는 객체 생성

 

2️⃣ logger.setLevel(logging.DEBUG) (출력할 로그 레벨 설정)

  • DEBUG 레벨 이상의 로그만 기록하도록 설정
  • DEBUG가 가장 낮은 레벨이므로 모든 로그(DEBUG, INFO, WARNING, ERROR, CRITICAL) 출력됨

 

3️⃣ 로그 형식 지정 (Formatter)

  • 로그 메시지의 출력 형식을 지정
  • %(asctime)s → 로그가 기록된 시간
  • %(name)s → 로거 이름
  • %(levelname)s → 로그 레벨 (DEBUG, INFO, WARNING, ERROR, CRITICAL)
  • %(message)s → 로그 메시지

 

4️⃣ 콘솔에 로그 출력 (StreamHandler)

  • StreamHandler() → 로그를 터미널(콘솔)에 출력하는 핸들러를 생성
  • setFormatter(formatter) → 로그 형식을 적용함.
  • addHandler(stream_handler) → 로거에 추가해서 실행되도록 설정.

 

5️⃣ 로그 파일에 저장 (FileHandler)

  • FileHandler('sample2.log', encoding="utf-8") → 로그를 sample2.log 파일에 저장.
  • setFormatter(formatter) → 파일에도 동일한 로그 형식을 적용.
  • addHandler(file_handler) → 파일에 로그를 저장하도록 설정.

 

스케줄러

sched

sched는 지정된 시간 간격으로 원하는 이벤트를 실행하게 하는 이벤트 스케줄러 표준라이브러리
사용 순서
1. 스케줄러 객체 생성
2. enter(실행간격(초), 우선순위, 실행할 함수, 함수에 전달할 인자)를 사용하여 실행할 이벤트 등록
3. run() 스케줄러 실행

 

 

예제

import sched
import time

start = time.time()

def print_a(a):
    print(round(time.time() - start, 2), ' 초 경과')
    print(a)


def print_b(b):
    print(round(time.time() - start, 2), ' 초 경과')
    print(b)


def print_c(c):
    print(round(time.time() - start, 2), ' 초 경과')
    print(c)


s = sched.scheduler()  # 스케줄러 객체 생성
s.enter(5, 1, print_a, ('print_a 함수 실행됨',))  # 5초 후에 실행
s.enter(3, 1, print_b, ('print_b 함수 실행됨',))  # 3초 후에 실행
s.enter(7, 1, print_c, ('print_c 함수 실행됨',))  # 7초 후에 실행
s.run()

 

3.01  초 경과
print_b 함수 실행됨
5.02  초 경과
print_a 함수 실행됨
7.01  초 경과
print_c 함수 실행됨

 

schedule

sched과 마찬가지로 일정한 시간 간격으로 프로그램을 실행시켜주는 외장 라이브러리
파이썬의 원하는 함수들을 원하는 실행 주기를 (초, 분, 시간, 요일, 특정 시각) 손쉽게 설정이 가능
시간 관련 내장 라이브러리인 time과 주로 함께 사용됨

 

예제

5초에 한번씩 함수 실행

import schedule
import time

def message(interval):
    print(f"{interval}간격 스케줄 실행중...")
    
# 5초에 한번씩 함수 실행
schedule.every(5).seconds.do(message, '5초')  # 이벤트 등록

# 스케줄러 실행
while True:
    schedule.run_pending()

 

 

여러 시간대 함수 실행

# 스케줄러 초기화
# 초기화 시켜줘야함
schedule.clear()

# 1분에 한번씩 함수 실행
schedule.every(1).minutes.do(message, '1분') 

# 1시간에 한번씩 함수 실행
schedule.every(1).hour.do(message, '1시간')

# 1일에 한번씩 함수 실행
schedule.every(1).days.do(message, '1일')

# 1주에 한번씩 함수 실행
schedule.every(1).weeks.do(message, '1주')

# 매일 13시 30분에 함수 실행
schedule.every().day.at("13:30").do(message, '1일')

# 매일 "11:11:11"에 함수 실행
schedule.every().day.at("11:11:11").do(message, '1일')

# 매주 월요일 13시 30분에 함수 실행
schedule.every().monday.at("13:30").do(message, '1주')

 

스케줄러 중지

# job 설정
job = schedule.every(1).seconds.do(message, '1초')  # 이벤트 등록

# 스케줄러 실행
count = 0

while True:
    schedule.run_pending()
    time.sleep(1)
    
    count = count + 1
    
    if count > 5:  # 5회 실행 후 스케줄러 중지
        schedule.cancel_job(job)
        print('스케줄러가 종료되었습니다 !')
        break

1초간격 스케줄 실행중...
1초간격 스케줄 실행중...
1초간격 스케줄 실행중...
1초간격 스케줄 실행중...
1초간격 스케줄 실행중...
스케줄러가 종료되었습니다 !

 

'Python > 학습용' 카테고리의 다른 글

N배 빠른 크롤링(3)  (0) 2025.02.23
N배 빠른 크롤링(2)  (0) 2025.02.23
[ML] 비지도학습  (0) 2025.01.29
Python-SQL 연결(데이터 추출)  (0) 2025.01.25
머신러닝 프로젝트 분석  (0) 2025.01.21