반응형
반응형

입력된 웹 페이지 내에서 모든 <img> 요소를 추출하는 프로그램을 **requests**와 BeautifulSoup 라이브러리를 사용하여 구현해 드리겠습니다. 🔎

이 방법은 웹 크롤링(Web Crawling)의 가장 기본적인 형태이며, HTML을 파싱(Parsing)하여 원하는 특정 태그를 쉽게 찾아낼 수 있습니다.

 

_image_resource_extract.py

 

import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin, urlparse
import sys

def extract_images_from_url(url):
    """
    주어진 URL의 웹 페이지에서 모든 <img> 태그의 src 속성을 추출합니다.
    
    :param url: 분석할 웹 페이지의 URL
    :return: 이미지 URL 리스트
    """
    if not (url.startswith('http://') or url.startswith('https://')):
        # 사용자가 프로토콜을 생략했을 경우 https://를 기본으로 추가
        url = 'https://' + url
        
    image_list = []
    
    print(f"URL에 접속 중: {url}")
    
    try:
        # 1. HTTP 요청 보내기
        # User-Agent를 설정하여 봇 접근이 아님을 알리고 접속 거부를 방지합니다.
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
        }
        response = requests.get(url, headers=headers, timeout=10)
        response.raise_for_status() # HTTP 오류가 발생하면 예외 발생
        
        # 2. HTML 파싱 (BeautifulSoup 사용)
        soup = BeautifulSoup(response.text, 'html.parser')
        
        # 3. 모든 <img> 태그 찾기
        img_tags = soup.find_all('img')
        
        # 4. 각 태그에서 src 속성 추출
        for img in img_tags:
            src = img.get('src')
            if src:
                # 5. 상대 경로를 절대 경로로 변환
                # <img src="/images/logo.png">와 같은 상대 경로를 처리하기 위해 필요합니다.
                absolute_url = urljoin(url, src)
                image_list.append(absolute_url)
                
    except requests.exceptions.RequestException as e:
        print(f"\n[오류] 웹 페이지에 접속할 수 없습니다: {e}")
        return None
    except Exception as e:
        print(f"\n[오류] 예상치 못한 오류가 발생했습니다: {e}")
        return None
        
    return image_list

if __name__ == "__main__":
    
    # 1. 사용자로부터 URL 입력 받기
    target_url = input("이미지 리스트를 추출할 웹 페이지 URL을 입력하세요 (예: google.com): ").strip()
    
    if not target_url:
        print("URL이 입력되지 않았습니다. 프로그램을 종료합니다.")
        sys.exit()

    # 2. 이미지 추출 실행
    images = extract_images_from_url(target_url)

    # 3. 결과 출력
    print("\n" + "="*50)
    
    if images is not None:
        print(f"📌 발견된 이미지 요소 개수: {len(images)}개")
        print("--- 추출된 이미지 URL 리스트 ---")
        
        # 최대 10개만 출력 (너무 길어지는 것을 방지)
        for i, img_url in enumerate(images[:10]):
            print(f"{i+1}. {img_url}")

        if len(images) > 10:
            print(f"...\n(총 {len(images)}개의 이미지 URL이 발견되었습니다.)")
    
    print("="*50)
반응형
반응형

YouTube 또는 기타 지원되는 웹사이트의 영상 URL에 대해 **사용 가능한 모든 다운로드 형식(Format)**의 목록을 세부 정보와 함께 출력하는 데 사용

 

설치 : pip install yt-dlp

 

 

yt-dlp --list-formats

 

yt-dlp --list-formats [오류가 발생한 YouTube URL]

 

 

반응형
반응형

 

[python] 유튜브 영상 경로로 다운받기 youtube_downloader.py

 

 

import yt_dlp
import os

def download_youtube_video():
    """사용자 입력 URL을 기반으로 YouTube 영상을 다운로드하는 함수"""
    
    url = input("다운로드할 YouTube 영상 URL을 입력하세요: ").strip()
    
    if not url:
        print("경고: 유효한 URL을 입력해야 합니다.")
        return

    # 📌 수정 1: 다운로드 폴더 경로 설정 
    current_dir = os.getcwd() # 현재 스크립트가 실행되는 디렉토리
    download_dir = os.path.join(current_dir, 'downloads') # 'downloads' 하위 폴더 경로 생성
    
    # 📌 수정 2: 'downloads' 폴더가 없으면 생성
    if not os.path.exists(download_dir):
        os.makedirs(download_dir)
        print(f"[알림] 'downloads' 폴더를 생성했습니다: {download_dir}")

    # 2. 다운로드 옵션 설정
    ydl_opts = {
        #'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best', 
        'format': 'bestvideo+bestaudio/best',
        
        # 📌 수정 3: outtmpl 옵션에 'download_dir' 경로 추가
        # outtmpl 옵션: 저장될 파일의 템플릿 (경로 포함)
        'outtmpl': os.path.join(download_dir, '%(title)s.%(ext)s'), 
        
        'postprocessors': [{
            'key': 'FFmpegMetadata',
            'add_metadata': True,
        }],
    }

    # 3. 다운로드 실행
    try:
        print(f"\n[알림] 다운로드를 시작합니다: {url}")
        
        with yt_dlp.YoutubeDL(ydl_opts) as ydl:
            ydl.download([url])
            
        print("\n🎉 다운로드가 성공적으로 완료되었습니다!")
        print(f"저장된 위치: {download_dir}")
        
    except yt_dlp.utils.DownloadError as e:
        print(f"\n[오류] 다운로드 중 오류가 발생했습니다: {e}")
    except Exception as e:
        print(f"\n[오류] 예상치 못한 오류가 발생했습니다: {e}")


if __name__ == "__main__":
    download_youtube_video()
반응형
반응형

랜덤 워크(Random Walk)를 사용하여 **아트적인 노이즈 트레일(Artistic Noise Trail)**을 만드는 것은 제너레이티브 아트(Generative Art)에서 매우 흔하고 흥미로운 기법입니다. 이는 각 단계에서 **무작위성(Stochasticity)**을 이용해 경로를 결정함으로써 예측 불가능하면서도 유기적인 움직임을 만들어냅니다.

 

파이썬에서는 주로 turtle 또는 **matplotlib**을 사용하여 시각화할 수 있지만, 여기서는 제너레이티브 아트에 자주 사용되는 접근 방식인 랜덤 증분을 이용해 구현해 보겠습니다.

 

"""
랜덤 워크(Random Walk)를 사용하여 **아트적인 노이즈 트레일(Artistic Noise Trail)**을 만드는 것은 제너레이티브 아트(Generative Art)에서 매우 흔하고 흥미로운 기법입니다. 이는 각 단계에서 **무작위성(Stochasticity)**을 이용해 경로를 결정함으로써 예측 불가능하면서도 유기적인 움직임을 만들어냅니다.

파이썬에서는 주로 turtle 또는 **matplotlib**을 사용하여 시각화할 수 있지만, 여기서는 제너레이티브 아트에 자주 사용되는 접근 방식인 랜덤 증분을 이용해 구현해 보겠습니다.

"""


import numpy as np
import matplotlib.pyplot as plt

def generate_random_walk_trail(steps, noise_strength=1):
    """
    주어진 단계 수만큼 랜덤 워크 트레일 데이터를 생성합니다.
    
    :param steps: 랜덤 워크를 진행할 단계 수
    :param noise_strength: 노이즈/이동 강도 (클수록 경로가 거칠어짐)
    :return: x, y 좌표 배열
    """
    # 각 단계에서의 x, y 변화량 (랜덤 증분)을 생성합니다.
    # -noise_strength부터 +noise_strength 사이의 균일 분포 난수
    dx = np.random.uniform(-noise_strength, noise_strength, steps)
    dy = np.random.uniform(-noise_strength, noise_strength, steps)

    # 누적합을 계산하여 경로(트레일)를 만듭니다.
    # 각 지점은 이전 지점에서의 변화량을 누적한 결과입니다.
    x_trail = np.cumsum(dx)
    y_trail = np.cumsum(dy)
    
    return x_trail, y_trail

# --- 시각화 설정 ---
STEPS = 5000  # 경로 길이
NOISE_LEVEL = 1.5 # 노이즈 강도 조절

x_coords, y_coords = generate_random_walk_trail(STEPS, NOISE_LEVEL)

# Matplotlib으로 트레일 시각화
fig, ax = plt.subplots(figsize=(10, 10))
ax.plot(x_coords, y_coords, 
        color='white',      # 선 색상
        linewidth=0.5,      # 선 두께
        alpha=0.8)          # 투명도

# 배경 및 축 설정
ax.set_facecolor('black')
ax.set_xticks([])
ax.set_yticks([])
ax.set_title(f"Random Walk Artistic Noise Trail ({STEPS} steps)", color='white')

# 축 비율을 같게 설정하여 왜곡 방지
ax.set_aspect('equal', adjustable='box')

plt.show()

 

 

 

 

import numpy as np
import matplotlib.pyplot as plt

steps = np.random.choice([1, -1], size=(2,1000))
pos = np.cumsum(steps, axis=1)
plt.plot(pos[0], pos[1], color='lime')
plt.axis('off')
plt.title("Random walk path", color='green')
plt.show()

 

반응형
반응형

turtle 로 전체화면에서 임의로 선그리기 

 

import turtle
import random

# 화면 설정
def setup_screen():
    """창을 설정하고 전체 화면과 유사하게 최대화합니다."""
    screen = turtle.Screen()
    screen.setup(width=1.0, height=1.0) # 화면 크기를 최대화합니다.
    screen.title("무작위 선 그리기 (전체 화면)")
    screen.colormode(255) # RGB 색상 모드를 0-255로 설정합니다.
    screen.bgcolor("black") # 배경색을 검은색으로 설정합니다.
    screen.tracer(0) # 그리기 속도를 높이기 위해 자동 화면 업데이트를 끕니다.
    return screen

# 거북이 설정
def setup_turtle():
    """선을 그릴 거북이를 설정합니다."""
    t = turtle.Turtle()
    t.hideturtle() # 거북이 아이콘을 숨깁니다.
    t.speed(0) # 최고 속도로 설정합니다.
    t.pensize(2) # 펜 두께를 설정합니다.
    return t

# 무작위 색상 생성
def get_random_color():
    """무작위 RGB 색상 튜플을 반환합니다."""
    r = random.randint(0, 255)
    g = random.randint(0, 255)
    b = random.randint(0, 255)
    return (r, g, b)

# 메인 그리기 루프
def draw_random_lines(t, screen):
    """화면이 종료될 때까지 무작위 선을 계속 그립니다."""
    while True:
        # 무작위 색상 및 위치 설정
        color = get_random_color()
        t.pencolor(color)
        
        # 펜을 든 상태로 무작위 위치로 이동 (현재 위치에서 그리기 시작)
        t.left(random.randint(-180, 180)) # 무작위로 방향을 돌립니다.
        
        # 무작위 길이만큼 앞으로 이동 (선을 그림)
        distance = random.randint(50, 300)
        t.forward(distance)

        # 화면 가장자리를 벗어났는지 확인하고, 벗어났다면 펜을 들고 중앙 근처로 이동
        # 이 과정이 없으면 거북이가 화면 밖으로 나가버려 그림이 멈춘 것처럼 보일 수 있습니다.
        current_x, current_y = t.position()
        screen_width = screen.window_width()
        screen_height = screen.window_height()
        
        if abs(current_x) > screen_width / 2 or abs(current_y) > screen_height / 2:
            t.penup() # 펜 들기
            t.goto(0, 0) # 중앙으로 이동
            t.left(random.randint(-180, 180)) # 방향을 다시 무작위로 설정
            t.pendown() # 펜 내리기
            
        # 화면 업데이트 (tracer(0)를 사용했으므로 수동으로 업데이트)
        screen.update()

# 프로그램 실행
if __name__ == "__main__":
    screen = setup_screen()
    t = setup_turtle()
    
    try:
        draw_random_lines(t, screen)
    except turtle.Terminator:
        # 창 닫기 버튼을 눌렀을 때 발생하는 예외 처리
        print("프로그램이 종료되었습니다.")
    except Exception as e:
        print(f"예외 발생: {e}")
        
    # 창을 닫을 때까지 프로그램이 대기하도록 함 (실제 draw_random_lines 루프에서는 필요 없음)
    # turtle.done()
반응형
반응형

 

[python] asciichartpy -  터미널(콘솔) 환경에 깔끔하고 읽기 쉬운 텍스트 기반의 ASCII 아트 그래프를 그려주는 라이브러리

 

pip install asciichartpy

 

https://pypi.org/project/asciichartpy/

 

Client Challenge

JavaScript is disabled in your browser. Please enable JavaScript to proceed. A required part of this site couldn’t load. This may be due to a browser extension, network issues, or browser settings. Please check your connection, disable any ad blockers, o

pypi.org

 

 

import asciichartpy 

data = [1, 2, 3, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 4, 3, 2, 1]
print("ASCll Line Chart Example")
print(asciichartpy.plot(data, {'height': 10}))

 

import asciichartpy as ac

series1 = [20, 25, 22, 28, 30, 24, 35, 32, 26]
series2 = [10, 15, 12, 18, 20, 14, 25, 22, 16]

# 두 개의 계열을 하나의 차트에 표시
print(ac.plot([series1, series2], {'height': 15, 'colors': [ac.red, ac.blue]}))
반응형

+ Recent posts