##############################################################################################
# 프로그램 설명 : 웹 크롤링을 통해 컴퓨터 부품 가격 정보를 수집하여 데이터베이스에 저장하는 프로그램 #
##############################################################################################

import requests
from bs4 import BeautifulSoup
from datetime import datetime
import re
import mysql.connector

# MySQL 데이터베이스 연결 설정
from db_config import conn, cursor  # db_config.py에서 conn과 cursor를 가져옴

# 데이터베이스 테이블 생성 (필요 시)
try:
    cursor.execute('''
    CREATE TABLE IF NOT EXISTS api_get_price_cpu (
        id INT AUTO_INCREMENT PRIMARY KEY,
        ca1 VARCHAR(255),
        ca2 VARCHAR(255),
        product VARCHAR(255) UNIQUE,
        price INT,
        price_prev INT,
        datetime DATETIME,
        datetime_prev DATETIME
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
    ''')
    conn.commit()
    print("Table created successfully.")
except mysql.connector.Error as err:
    print(f"Error: {err}")

# URL 목록 정의
urls = {
    'cpu_intel': 'https://www.worldmemory.co.kr/price/computer.do?searchText=%20&ctgry_no1=8&ctgry_no2=9&ctgry_no3=4144',
    'cpu_amd': 'https://www.worldmemory.co.kr/price/computer.do?searchText=%20&ctgry_no1=8&ctgry_no2=24&ctgry_no3=4138',
    'ram_desktop': 'https://www.worldmemory.co.kr/price/computer.do?searchText=%20&ctgry_no1=1&ctgry_no2=2&ctgry_no3=7',
    'ram_notebook': 'https://www.worldmemory.co.kr/price/computer.do?searchText=%20&ctgry_no1=1&ctgry_no2=3&ctgry_no3=4142',
    'hdd': 'https://www.worldmemory.co.kr/price/computer.do?searchText=%20&ctgry_no1=10&ctgry_no2=57&ctgry_no3=70',
    'ssd': 'https://www.worldmemory.co.kr/price/computer.do?searchText=%20&ctgry_no1=10&ctgry_no2=966&ctgry_no3=967',
    'gpu_nvidia': 'https://www.worldmemory.co.kr/price/computer.do?searchText=%20&ctgry_no1=14&ctgry_no2=58&ctgry_no3=4145',
    'gpu_ati': 'https://www.worldmemory.co.kr/price/computer.do?searchText=%20&ctgry_no1=14&ctgry_no2=59&ctgry_no3=4146',
    'mb_intel': 'https://www.worldmemory.co.kr/price/computer.do?searchText=%20&ctgry_no1=12&ctgry_no2=42&ctgry_no3=4090',
    'mb_amd': 'https://www.worldmemory.co.kr/price/computer.do?searchText=%20&ctgry_no1=12&ctgry_no2=4026&ctgry_no3=4139',
    'GalaxyTab': 'https://www.worldmemory.co.kr/price/computer.do?searchText=%20&ctgry_no1=4116&ctgry_no2=4117&ctgry_no3=4120',
    'MacBookPro': 'https://www.worldmemory.co.kr/price/computer.do?searchText=%20&ctgry_no1=21&ctgry_no2=1756&ctgry_no3=4147',
    'MacBookAir': 'https://www.worldmemory.co.kr/price/computer.do?searchText=%20&ctgry_no1=21&ctgry_no2=1759&ctgry_no3=4163',
    'iPad': 'https://www.worldmemory.co.kr/price/computer.do?searchText=%20&ctgry_no1=21&ctgry_no2=65&ctgry_no3=4115',
    'iMac': 'https://www.worldmemory.co.kr/price/computer.do?searchText=%20&ctgry_no1=21&ctgry_no2=64&ctgry_no3=4162',
}

# 요청 헤더 설정
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}

# 방문한 링크를 기억하기 위한 집합
visited_links = set()

def clean_price(price_str):
    """가격 문자열을 정수형으로 변환하는 함수"""
    price_str_clean = re.sub(r'[^\d]', '', price_str)
    return int(price_str_clean) if price_str_clean else 0

def process_page(url, ca1):
    """페이지를 크롤링하여 데이터베이스에 저장하는 함수"""
    if url not in visited_links:
        visited_links.add(url)

        # 웹 페이지 요청
        response = requests.get(url, headers=headers)
        print(f"Main Page URL: {url} | Status Code: {response.status_code}")

        # 요청이 성공했는지 확인
        if response.status_code == 200:
            # 페이지 내용을 BeautifulSoup으로 파싱
            soup = BeautifulSoup(response.text, 'html.parser')

            # 데이터가 포함된 부분을 정확히 선택하여 추출
            table = soup.find('table')  # 실제 테이블 태그 선택
            if table:
                rows = table.find_all('tr')  # 모든 행을 찾음
                for row in rows:
                    cols = row.find_all('td')  # 각 행의 셀을 찾음
                    cols = [col.get_text(strip=True) for col in cols]
                    if len(cols) >= 2:  # 최소 2개의 열이 필요
                        try:
                            # 첫 번째 <td> 값은 ca2로 기록
                            ca2 = cols[0]
                            # 두 번째 <td> 값은 product로 기록
                            product = cols[1]
                            price_str = cols[2] if len(cols) > 2 else ""
                            price = clean_price(price_str)

                            # price가 0이 아닌 경우에만 처리
                            if price > 0:
                                # 현재 시간 기록
                                current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')

                                # 데이터베이스에 삽입 또는 업데이트
                                cursor.execute('''
                                    INSERT INTO api_get_price_cpu (ca1, ca2, product, price, datetime)
                                    VALUES (%s, %s, %s, %s, %s)
                                    ON DUPLICATE KEY UPDATE
                                    price = CASE
                                        WHEN price <> VALUES(price) THEN VALUES(price)
                                        ELSE price
                                    END,
                                    price_prev = CASE
                                        WHEN price <> VALUES(price) THEN price
                                        ELSE price_prev
                                    END,
                                    datetime_prev = CASE
                                        WHEN price <> VALUES(price) THEN datetime
                                        ELSE datetime_prev
                                    END,
                                    datetime = CASE
                                        WHEN price <> VALUES(price) THEN %s
                                        ELSE datetime
                                    END
                                ''', (ca1, ca2, product, price, current_time, current_time))

                                print(f"Ca1: {ca1}")
                                print(f"Ca2: {ca2}")
                                print(f"Product: {product}")
                                print(f"Price: {price}")
                                print("----")
                        except ValueError as ve:
                            print(f"ValueError: {ve} - Row data: {cols}")

            # 다른 페이지 링크 추출
            links = soup.find_all('a', href=True)
            for link in links:
                href = link['href']
                # 링크가 상대경로일 경우 절대경로로 변환
                if not href.startswith('http'):
                    href = requests.compat.urljoin(url, href)

                # 링크가 이미 방문한 링크인지 확인
                if href not in visited_links:
                    visited_links.add(href)

                    # 각 링크에서 데이터 추출
                    process_page(href, ca1)

# URL 목록을 순회하며 데이터 크롤링
for ca1, url in urls.items():
    process_page(url, ca1)

# 변경 사항 커밋
conn.commit()

# 데이터베이스 연결 종료
cursor.close()
conn.close()
