반응형
온라인 쇼핑몰에서 내가 원하는 부분의 리뷰 데이터만 가져오는 웹크롤링을 해보기로 했다
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 |