• 티스토리 홈
  • 프로필사진
    31514
  • 방명록
  • 공지사항
  • 태그
  • 블로그 관리
  • 글 작성
31514
  • 프로필사진
    31514
    • 분류 전체보기 (106) N
      • Book (66)
        • Learning SQL (9)
        • SQL 레벨업 (8)
        • 견고한 데이터 엔지니어링 (5)
        • 운영체제 (2)
        • 스파크 완벽 가이드 (9)
        • 파이썬 코딩의 기술 (29)
        • 분산 컴퓨팅 (4)
      • 개발 (24) N
      • 기타 (10)
        • 출퇴근 공부 간단 정리 (7)
      • ELK (6)
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
      등록된 댓글이 없습니다.
    • 최근 공지
      • 31514의 이전 블로그는 여기로!
      등록된 공지가 없습니다.
    # Home
    # 공지사항
    #
    # 태그
    # 검색결과
    # 방명록
    • lazy load되는 컨텐츠 안정성있게 크롤링하기
      2024년 10월 25일
      • 31514
      • 작성자
      • 2024.10.25.:39

      상황 및 문제

      프로젝트에 사용할 데이터를 확보하기 위해서 디올 공식 홈페이지에 있는 상품을 크롤링했다.

      디올은 스크롤 다운할 때마다 동적으로 지연 로딩되는 방식으로 구현되어있다.

      이에 따라 디올 홈페이지의 최하단까지 스크롤 다운하고, 원하는 요소를 모두 가져오는 방식으로 크롤링을 진행하였다.

       

      하지만 매번 프로그램을 실행할 때마다 가져오는 로딩된 요소의 수가 불안정했다.

      예를 들어 정상적으로 로딩된 요소는 다음과 같이 구성되어있다.

      <div class="lazyload-wrapper "><div class="DS-Card MuiBox-root mui-style-11cdi2h" ...

       

      하지만 로딩되지 않은 요소를 살펴보니 다음과 같았다.

      <div class="lazyload-wrapper "><div class="lazyload-placeholder"></div></div>

       

      해결 시도 1

      lazy loading되는 요소를 충분히 기다리기 위해서 스크롤다운 할 때마다 기다리는 시간을 추가하고, 최하단까지 내려갔을 때도 Time Wait을 걸었다.

      await page.wait_for_timeout(3000)

       

      하지만 아무리 시간을 길게 걸어도, 문제는 해결되지 않았다.

       

      결과

      결국에는 스크롤 다운할 때마다 div 태그의 클래스 이름이 lazyload-placeholder인 요소가 있으면 처음으로 돌아가서 다시 스크롤 다운하는 방법으로 해결했다.

       

      만약 playwright을 사용한다면 다음과 같은 코드를 사용할 수 있다.

      async def scroll_to_bottom(page):
          previous_height = await page.evaluate('document.body.scrollHeight')
      
          while True:
              # 스크롤을 가장 아래로 내림
              await page.evaluate('window.scrollTo(0, document.body.scrollHeight)')
              # 스크롤 후 페이지 로드 대기 (네트워크 요청 등)
              await page.wait_for_timeout(1000)
      
              # 현재 높이를 다시 가져옴
              new_height = await page.evaluate('document.body.scrollHeight')
      
              # lazyload-placeholder가 있는지 확인
              placeholders = await page.query_selector_all("div.lazyload-placeholder")
      
              if placeholders:
                  print("lazyload-placeholder가 감지되었습니다. 위로 스크롤합니다.")
                  await page.evaluate('window.scrollTo(0, 0)')
                  await page.wait_for_timeout(1000)
      
                  # 다시 최하단으로 스크롤
                  await page.evaluate('window.scrollTo(0, document.body.scrollHeight)')
                  await page.wait_for_timeout(1000)
              else:
                  print("모든 콘텐츠가 로드되었습니다.")
                  break
      
              # 더 이상 스크롤할 수 없으면 종료
              if new_height == previous_height:
                  break
      
              previous_height = new_height

       

      느낀점

      솔직히 이 해결 방법이 좋은 방향이라고 단정 지을 수는 없지만, 일단 더 찾아봐도 더 나은 방법을 찾아볼 수는 없었다.

      후에 나의 실력이 더 늘어나면 보다 넓은 시야로 바라볼 수 있기를 바래본다.

      '개발' 카테고리의 다른 글

      GCP VM Instance 저스펙으로 Airflow 서버 구축하고 안정적으로 크롤링하기  (0) 2024.11.14
      홈 서버 구축기인데 LG U+를 곁들인..  (1) 2024.11.01
      뤼튼 캐릭터 크롤링  (1) 2024.10.13
      [MySQL] DELETE & UPDATE  (0) 2024.10.04
      멀티 프로세싱 & 멀티 스레딩 & 비동기 처리  (0) 2024.10.02
      다음글
      다음 글이 없습니다.
      이전글
      이전 글이 없습니다.
      댓글
    조회된 결과가 없습니다.
    스킨 업데이트 안내
    현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
    ("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
    목차
    표시할 목차가 없습니다.
      • 안녕하세요
      • 감사해요
      • 잘있어요

      티스토리툴바