[Way to PM] 사이드 프로젝트

[Way to PM] 사이드 프로젝트 1. python 몰라도 웹스크래핑 시스템 코드 구축하기 1장

송재훈 2024. 2. 10. 23:44

0. 레퍼런스

 

왼쪽에서부터 웹사이트의 상-하단부

 

1. 우선 순위 설정

1) Chat GPT 이용해서 python으로 이미지 크롤러 만들기 

2) 클로링한 이미지를 이용해 Google Teachable Machine으로 ML모델 만들기

3) HTML과 ML 연동해 간단한 축구 유니폼 추천 사이트 구축

*(CSS로 기본적인 정리)

**참고영상(https://www.youtube.com/watch?v=1b7pXC1-IbE)

2. WHY - 해당 과제를 통해 얻고자 하는 목표

1) Chat GPT라는 기술을 이용해 python에 대한 지식이 없어도 크롤링 시스템 구축하여 신기술을 직접 이용해보고 적용하는 경험 쌓기

2) 이미지 데이터 수집해서 ML모델 만들어보는 경험 쌓기

3) 구축한 ML모델을 이용할 수 있는 웹사이트 구축

 

3. HOW - 구현한 코드

전체 코드

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver import ChromeOptions
import requests
from PIL import Image
import io
import os


# from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException

def download_image(image_url, folder_name):
    if not os.path.isdir(folder_name):
        os.makedirs(folder_name)

    try:
        response = requests.get(image_url, stream=True)
        if response.status_code == 200:
            # Open the image and convert it to JPG
            image = Image.open(io.BytesIO(response.content)).convert('RGB')

            # Create a filename based on the number of images in the folder
            safe_image_name = f"{len(os.listdir(folder_name)) + 1}.jpg"
            image_file_path = os.path.join(folder_name, safe_image_name)

            # Save the image as JPG
            image.save(image_file_path, 'JPEG')
    except Exception as e:
        print(f"Could not download or convert {image_url}. Error: {e}")

def fetch_image_urls(driver, base_url, max_images):
    image_urls = set()
    current_page = 1

    while len(image_urls) < max_images:
        if current_page == 1:
            driver.get(base_url)  # URL for the first page
        else:
            driver.get(f"{base_url}/page/{current_page}/")  # URL for subsequent pages

        try:
            # Use WebDriverWait to wait for the image elements to be present
            WebDriverWait(driver, 10).until(
                EC.presence_of_all_elements_located((By.CSS_SELECTOR, "img.render"))
            )
        except TimeoutException:
            print(f"Timeout while waiting for images on page {current_page}")

        thumbnails = driver.find_elements(By.CSS_SELECTOR, "img.render")
        # ... rest of your code
        if not thumbnails:  # If no elements found, try with 'img.renderMeta'
            thumbnails = driver.find_elements(By.CSS_SELECTOR, "img.renderMeta")

        for img in thumbnails:
            src = img.get_attribute('src')
            if src and src not in image_urls:
                image_urls.add(src)
                if len(image_urls) >= max_images:
                    return list(image_urls)

        current_page += 1

    return list(image_urls)

# Set up the Selenium WebDriver
options = ChromeOptions()
options.add_experimental_option("detach", True)
driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()), options=options)

# Define base URL and number of images to download
base_url = "https://www.footyrenders.com/premier-league/wolverhampton-wanderers"
max_images = 400  # Set your desired number of images

# Fetch image URLs
urls = fetch_image_urls(driver, base_url, max_images)

# Download images and convert them to JPG
for url in urls:
    download_image(url, 'wolverhampton-wanderers')

# Close the WebDriver
driver.quit()

문제해결 과정 1.

1) 문제 상황 발생: chrome driver로 스크래핑을 위해 웹에 접속을 하면 자꾸 크롬이 꺼지는 문제

2) 문제 원인 탐색: 

-구글링을 통해 Stackoverflow에서 수정된 코드 적용 -> 문제 해결 안됨

-Firefox로 시스템을 가동하면 꺼지지 않고 작동함을 확인

-time.sleep 메서드 적용시 문제없이 작동

-코드에서의 문제가 있다기 보단 크롬과 드라이버의 버전 호환이 안되는 문제라고 판단

-selenim라이브러리 업데이트와 driver 최신버전, 구버전 모두 다운받아 가동했으나 문제 상황 반복

**웹드라이버와 크롬의 호환성 문제라고 생각했으나 해당 글을 작성하면서 진짜 문제는 셀레늄의 버전이 업그레이드 되면서 기존의 명령어가 적용되지 않아 더 이상 수행할 코드가 없어서 강제로 종료되었던 것

3) 문제 해결

# Selenium 임포트
from selenium import webdriver

# 크롬 드라이버 생성
driver = webdriver.Chrome('chromedriver 경로를 넣어 주세요')

기존의 코드대로 실행하면 오류없이 실행되나 드라이버로 실행한 크롬이 자꾸 꺼지게 된다.

from selenium.webdriver import ChromeOptions
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager

options = ChromeOptions()
options.add_experimental_option("detach", True)
driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()), options=options)

 해당 코드로 바꾸면서 크롬 브라우저가 닫히는 문제를 해결할 수 있었다.(구글링)

 두 코드는 Selenium을 사용하여 Chrome 브라우저를 자동화하기 위해 Chrome WebDriver를 초기화하는 방법에서 차이가 있다.

  • webdriver_manager 패키지를 사용하여 ChromeDriver의 설치와 관리를 자동화하고, ChromeDriverManager().install() 호출을 통해 자동으로 ChromeDriver를 다운로드하고, 필요한 경우 업데이트한다. 사용자가 ChromeDriver의 경로를 직접 지정할 필요가 없어진다. (기존에도 webdriver.exe를 코드파일과 같은 경로에 설치하면 selenium webdriver가 자동으로 코드파일과 같은 디렉토리 내에서 경로를 탐색한다.)
  • ChromeOptions를 사용하여 Chrome 드라이버에 추가 옵션을 설정한다. 여기서는 "detach": True 옵션을 추가하여 스크립트 실행 후 브라우저가 자동으로 닫히지 않도록 한다. 
  • ChromeService를 사용하여 ChromeDriver 서비스를 관리하며, 이는 더 세밀한 제어를 가능하게 한다.

4. WHAT - HOW에 있는 완성 코드

5. 배운점 및 자기평가

배운점

1) 라이브러리의 업데이트로 기존에 있던 코드 체계가 적용되지 않는 경우가 있다.

2) 문제발생 원인을 찾고자 할 때 원인이락 생각되는 부분을 명확히하고 해결해본다. 그럼에도 문제가 반복되면 다른 원인을 찾는다.(웹드라이버와 크롬의 버전 호환문제라고 생각해 웹드라이버를 몇 번이나 다운받고 지우고 설치하면서 시간을 너무 소비했다.)

3. 언어간에 차이는 있지만 객체지향, 클래스, 라이브러리 등 다른 언어에서 배운 개념이 유사하게 작용할 때가 있다. 접해본적이 없더라도 두려워할 필요 없다.

 

자기평가

1. 문제 발생 원인을 찾고 해결책을 적용했는데도 불구하고 문제 해결이 안되면 빠르게 다른 원인을 찾는다. 단, 넘어가기전에 기존의 원인과 해결책에 대해 확실히 해야한다. 이번 과저에선 그러지 못했다.