[본캠프 74일차] 최종 프로젝트 준비

월요일에 이어서 계속 프로젝트를 위한 데이터를 수집하는 웹 크롤링 코드를 짜는 중이다. 월요일에 헤어지기 전에 데이터 수집을 위한 동적 웹 크롤링에서 필요한 동작들이 어떤 부분들이 있는지 함께 확인하고 헤어졌다. 그리고 오늘 오전에 만나서 혹시 쉬는 동안 각자 웹 크롤링 관련해서 얼마나 진척이 있었는지 얘길 나누다가 팀원 중 한 분의 코드를 틀로 잡고 추가적으로 더 필요한 부분들을 각자 역할을 나눠서 해당 부분의 코드를 추가적으로 짜오는 일을 주로 했다. 웹 크롤링에서 시간이 많이 들거라 생각했던 것보다 작업 속도가 꽤 나서 만약에 원하는 대로 코드만 잘 돌아간다면 중간발표회가 있기 전에 EDA까지 충분히 해볼 수 있을 것 같다. (아마도..?)
오늘 한 일은,
- 최종 프로젝트 준비
- 데이터 수집을 위한 웹 크롤링 코드 짜기

우선 팀원분이 공유해주신 웹 크롤링 코드의 현재 상태는 다음과 같다.
- 웹 크롤링 하고자 하는 사이트에 접속해 로그인
- '편성표' 메뉴를 클릭
- '편성표' 페이지에서 원하는 필터들을 적용하기 (라방 분류, 라방 플랫폼, 일자 등)
- 해당 월의 1일에서 데이터를 수집한 후 다른 날짜로의 이동하여 수집하는 루프는 구현되지 않은 상황
- 해당 필터를 적용한 편성표 페이지(0월 0일의 편성표)의 방송 목록에서 각 방송 상세페이지로 접속해 각 라방 정보를 수집
(방송일, 방송 제목, 방송 시간, 조회수, 총 매출액, 총 판매 건수 등)

이런 코드를 갖고 있는 상황에서 추가적으로 수집해야 할 정보들을 각자 맡아서 수집하고 정리하기로 했는데, 내가 맡은 부분은 '판매상품' 목록을 수집하는 코드였다. 우리는 현재 데이터를 수집할 때 해당 방송 정보들을 담을 테이블 하나, 그리고 각 방송에서 판매한 상품들의 정보들을 담을 테이블 하나, 이렇게 각각 테이블을 만들고 추후에 해당 라이브 방송 상세 페이지의 url을 pk로 사용해 테이블을 병합할 계획이다.
아무튼 나는 저 판매상품에서 보이는 저 표에서 상품명, 정가, 판매가, 라이브가, 배송비, 라이브배송비, 판매량, 매출액에, 추후에 pk로 사용할 url까지 수집하는 코드를 짜야 한다.
# 첫 번째 작성한 코드
# ✅ 판매상품 테이블 수집 - 수정된 버전
product_rows = wait.until(
EC.presence_of_all_elements_located((By.CSS_SELECTOR, "table.Table_table___jpMW tbody tr"))
)
for row in product_rows:
try:
cols = row.find_elements(By.TAG_NAME, "td")
if len(cols) < 9: # 확인 결과 컬럼은 총 9개 (이미지 + 8개)
continue
product_data.append({
'URL': href, # 병합용 키
'상품명': cols[1].text.strip(),
'정가': cols[2].text.strip(),
'판매가': cols[3].text.strip(),
'라이브가': cols[4].text.strip(),
'배송비': cols[5].text.strip(),
'라이브배송': cols[6].text.strip(),
'판매량': cols[7].text.strip(),
'매출액': cols[8].text.strip()
})
except Exception as e:
print(f"❗️상품 파싱 실패: {e}")
driver.close()
driver.switch_to.window(original_window)
처음 작성한 코드는 위와 같다. 우선 팀원분이 공유해주신 파일에서 방송 상세 페이지까지 접속하는 부분까진 구현돼 있기 때문에 그 다음부터 코드를 수정했다.
1️⃣ 상품 테이블이 보일 때까지 대기하고
2️⃣ 상품 테이블의 컬럼들에서 컬럼들을 수집하여
3️⃣ 원하는 정보들을 앞서서 선언했던 product_data 변수에 딕셔너리 형태로 데이터를 담고
4️⃣ 열었던 방송 상세 페이지 창을 닫고서 원래 창으로 복귀
하는 흐름의 코드를 짰다.
해당 코드를 실행하여 최종적으로 csv 파일로까지 잘 저장됐다. 그래서 저장된 csv 파일을 보면서 각 방송의 판매 상품들이 잘 저장되었는지 확인하는데 수정해야 할 부분이 보였다.


해당 방송의 판매상품을 보면 총 30개의 상품을 판매했음을 확인할 수 있지만(좌측 캡쳐 이미지), 실제 저장된 csv 파일을 보면 첫 페이지에 보이는 상품 목록에서 노출된 10건만 가져왔음을 확인했다(우측 csv 파일 캡쳐 이미지). 그래서 해당 부분을 모두 가져오도록 동작을 추가해야 했다.
# 두 번째 작성한 코드(판매상품 테이블 보기 옵션 선택하는 동작 추가)
# ✅ 판매상품 테이블 수집 - 100개씩 보기로 설정
try:
# 드롭다운 버튼 클릭
dropdown_btn = wait.until(EC.element_to_be_clickable(
(By.CSS_SELECTOR, "div.SelectSmall_selectBox__bSJTd")
))
dropdown_btn.click()
time.sleep(0.5) # 드롭다운 애니메이션 기다리기
# li 요소 중에서 텍스트가 '100개씩 보기'인 항목 찾기
option_100 = wait.until(EC.element_to_be_clickable(
(By.XPATH, "//li[span[text()='100개씩 보기']]")
))
driver.execute_script("arguments[0].click();", option_100)
time.sleep(1)
# 테이블 로딩 대기
wait.until(EC.presence_of_all_elements_located(
(By.CSS_SELECTOR, "table.Table_table___jpMW tbody tr"))
)
time.sleep(1)
except Exception as e:
print(f"❗️100개 보기 설정 중 오류: {e}")
# ✅ 상품 정보 수집
try:
product_rows = driver.find_elements(By.CSS_SELECTOR, "table.Table_table___jpMW tbody tr")
for row in product_rows:
try:
cols = row.find_elements(By.TAG_NAME, "td")
if len(cols) < 9:
continue
product_data.append({
'URL': href,
'상품명': cols[1].text.strip(),
'정가': cols[2].text.strip(),
'판매가': cols[3].text.strip(),
'라이브가': cols[4].text.strip(),
'배송비': cols[5].text.strip(),
'라이브배송': cols[6].text.strip(),
'판매량': cols[7].text.strip(),
'매출액': cols[8].text.strip()
})
except Exception as e:
print(f"❗️상품 파싱 실패: {e}")
except Exception as e:
print(f"❗️상품 테이블 수집 실패: {e}")
driver.close()
driver.switch_to.window(original_window)
기존에 있던 상품 정보 수집 코드를 진행하기에 앞서서 판매상품이 한 페이지에 노출되는 보기 옵션을 기본 설정인 '10개씩 보기'에서 '100개씩 보기'로 변경하고서 진행하는 방향으로 동작 순서를 추가했다.
(원래는 판매상품 테이블 하단에 Pagination 부분을 활용해서 코드를 짜던 중에 팀원들과 얘기하면서 보기 옵션을 '100개씩 보기'로 변경해서 크롤링하는 편이 좋겠다고 판단하여서 이와 같이 진행하게 됐다)

이제 각자 작업한 코드들 취합해서 내일부터 본격적으로 데이터 수집에 들어갈 수 있을 것 같다..!