본문 바로가기
AI

(2023-12-26) 파이썬 프로젝트: 웹크롤링

by busybee-busylife 2023. 12. 28.
반응형

온라인 쇼핑몰에서 내가 원하는 부분의 리뷰 데이터만 가져오는 웹크롤링을 해보기로 했다 

 

 

1. 리뷰의 일부만 보여주는 부분을 '더보기' 버튼을 눌러서 더 많은 데이터를 펼쳐주는 함수 

def click_show_more_button(browser):
    try:
        # Find and click the "더보기" button
        more_button = browser.find_element(By.ID, 'btnMoreGod')
        more_button.click()
        # Wait for the content to load (adjust the timeout as needed)
        WebDriverWait(browser, 10).until(EC.staleness_of(more_button))
    except Exception as e:
        print(f"Exception occurred while clicking '더보기' button: {e}")
        print(f"Exception details: {str(e)}")

 

 

 

2. 원하는 카테고리를 설정 -> 정렬(최신순/판매량순/,,,) 후 해당 페이지에 나타난 제품의 코드만을 발췌 

# 제품코드 불러오는 함수 

def get_product_codes(url):

    parent = browser.find_element(By.CLASS_NAME, "product_list")
    all_links = parent.find_elements(By.TAG_NAME, 'a')

    href_list = []

    for link in all_links:
        href_text = link.get_attribute('href')
        href_list.append(href_text)

    item_list = href_list[::2]
    item_code = [item.split('/')[4] for item in item_list]

    browser.quit()  # 작업이 끝난 후 브라우저 종료

    return item_code

 

 

 

3. 날짜, 제목, 내용, url, 브랜드명, 아이템명, 가격 등 다양한 정보를 가져올 계획 

우선 빈 DataFrame을 만든다 

# 새로운 DataFrame을 만드는 함수 
def create_review_dataframe(date_list, title_list, content_list, url_list, brand_list, item_list, price_list):
    filtered_reviews = [(date, title, content, url, brand, item, price) for date, title, content, url, brand, item, price in
                        zip(date_list, title_list, content_list, url_list, brand_list, item_list, price_list)
                        if datetime.strptime(date, '%Y.%m.%d') >= datetime.strptime('2023.12.01', '%Y.%m.%d')]

    df = pd.DataFrame({'Date': [review[0] for review in filtered_reviews],
                       'Title': [review[1] for review in filtered_reviews],
                       'Content': [review[2] for review in filtered_reviews],
                       'URL': [review[3] for review in filtered_reviews],
                       'Brand': [review[4] for review in filtered_reviews],
                       'Item': [review[5] for review in filtered_reviews],
                       'Price': [review[6] for review in filtered_reviews]})

    return df

 

 

 

4. 각 항목들을 크롤링하는 함수를 만든다 

# 기존 DataFrame 생성
review_df = pd.DataFrame(columns=['Date', 'Title', 'Content', 'URL', 'Brand', 'Item', 'Price'])

def scrape_all_reviews(url, existing_df):
    # 웹 드라이버 초기화
    browser = webdriver.Chrome()
    browser.get(url)

    # 브랜드 이름 가져오기
    brand_element = browser.find_element(By.CSS_SELECTOR, '.prd_title_wrap .prd_title a.line_1')
    brand_name = brand_element.text

    # 아이템 이름 가져오기
    item_element = browser.find_element(By.CLASS_NAME, 'line_3')
    item_name = item_element.text

    # 가격 가져오기
    try:
        price_element = browser.find_element(By.CSS_SELECTOR, '.price_wrap .info_area span.current')
        price = price_element.text
    except NoSuchElementException:
        price = 'N/A'

    # 리뷰를 포함하는 iframe으로 전환
    iframe = browser.find_element(By.ID, 'crema-product-reviews-1')
    browser.switch_to.frame(iframe)

    title_list = []
    content_list = []
    date_list = []
    url_list = []
    brand_list = []
    item_list = []
    price_list = []

    while True:
        try:
            # 리뷰 데이터 추출
            all_reviews = browser.find_elements(By.CLASS_NAME, 'products_reviews_list')

            for review in all_reviews:
                date_elements = review.find_elements(By.CLASS_NAME, 'review_list_v2__date')
                date = [date.text for date in date_elements]
                date_list.extend(date)

                title_elements = review.find_elements(By.CLASS_NAME, 'review_list_v2__score_text')
                title = [title.text for title in title_elements]
                title_list.extend(title)

                content_elements = review.find_elements(By.CLASS_NAME, 'review_list_v2__message_container')
                content = [content.text for content in content_elements]
                filtered_content = [content[i] for i in range(len(content)) if i % 2 == 0]
                content_list.extend(filtered_content)

                url_list.append(url)
                brand_list.append(brand_name)
                item_list.append(item_name)
                price_list.append(price)

            # '리뷰 더보기' 제거
            content_list = [content.replace('리뷰 더보기', '') for content in content_list]

            # 다음 버튼이 비활성화되어 있는지 확인
            try:
                next_button = browser.find_element(By.CLASS_NAME, 'pagination__button--next')
                if 'pagination__button--disabled' in next_button.get_attribute('class'):
                    break
            except NoSuchElementException:
                break

            # 다음 버튼 클릭
            next_button.click()
            WebDriverWait(browser, 10).until(EC.staleness_of(all_reviews[-1]))

        except (TimeoutException, StaleElementReferenceException, NoSuchElementException) as e:
            print(f"Exception occurred: {e}")

    # 날짜를 기준으로 리뷰 필터링
    filtered_reviews = [(date, title, content, url, brand, item, price) for date, title, content, url, brand, item, price in
                        zip(date_list, title_list, content_list, url_list, brand_list, item_list, price_list)
                        if datetime.strptime(date, '%Y.%m.%d') >= datetime.strptime('2023.12.01', '%Y.%m.%d')]

    # 새로운 리뷰를 기존 DataFrame에 추가
    existing_df = pd.concat([existing_df, pd.DataFrame(filtered_reviews, columns=['Date', 'Title', 'Content', 'URL', 'Brand', 'Item', 'Price'])], ignore_index=True)

    # 브라우저 종료
    browser.quit()

    # 데이터프레임 반환
    return existing_df

 

 

 

5. 위에서 만든 제품코드 함수(2번)로 가져온 제품코드 리스트에 해당하는 모든 제품의 리뷰를 가져오기 위해 

    for-loop으로 각 제품코드 별 4번 함수를 반복한다 

for product in product_codes:
    product_url = f'https://www.eqlstore.com/product/{product}/detail'
    print(product_url)
    
    # 기존 데이터프레임에 리뷰 추가
    review_df = scrape_all_reviews(product_url, review_df)

# 최종 데이터프레임을 CSV 파일로 저장
review_df.to_csv('reviews_data.csv', index=False, encoding='utf-8')

# 저장된 CSV 파일을 읽어와서 출력
final_df = pd.read_csv('reviews_data.csv')
print(final_df)
반응형

'AI' 카테고리의 다른 글

(2024-01-17) 통계  (0) 2024.01.24
(2023-12-29) Python EDA  (0) 2024.01.10
(2023-12-13) 왜 파이썬인가 /  (0) 2023.12.13
(2023-12-12) 특강  (0) 2023.12.12
(2023-12-11) OT  (0) 2023.12.11