목차

  1. 필수 라이브러리 준비
  2. 스크립트 설명
  3. 실행 방법
  4. 결과 확인


필수 라이브러리 준비

  1. Redis 설치 및 실행

    스크립트는 Redis 서버를 사용하여 큐를 관리합니다. 따라서 Redis 서버가 설치되어 있어야 합니다. 설치 및 실행 방법은 다음과 같습니다:

    Ubuntu

    sudo apt update
    sudo apt install redis -y
    sudo systemctl start redis
    

    → Redis가 실행 중인지 확인. “PONG” 나오면 제대로 설치완료.

    redis-cli ping
    
  2. wkhtmltoimage 설치

    URL의 이미지를 생성하기 위해 ‘wkhtmltoimage’ 라이브러리가 필요합니다.

    Ubuntu

    sudo apt install wkhtmltopdf -y
    


    스크립트 설명

    1. 생성자 스크립트(’ producer.sh ’)

      쉘스크립트 생성 후 스크립트를 끼워넣는다.

      생성자 스크립트는 주어진 URL과 시작 인덱스를 기반으로 Redis Queue에 URL을 추가해야합니다.

      #!/bin/bash
      
      # Redis의 'scrap_queue'를 삭제합니다. 출력은 /dev/null로 리다이렉트하여 무시합니다.
      redis-cli del scrap_queue > /dev/null
      
      # 스크래핑할 기본 URL을 설정합니다.
      SCRAP_URL="<https://www.daangn.com/articles/>"
      
      # 동시에 실행할 최대 프로세스 수를 설정합니다.
      MAX_PROCESS=3
      
      # 시작할 기사 번호를 설정합니다.
      # 게시글이 삭제되었거나 없는 경우도 그대로 캡쳐 됩니다.
      START_ARTICLE_IDX=2784783301
      
      # 스크래핑할 총 기사 수를 설정합니다.
      SCRAP_TARGET_CNT=100
      
      # 설정된 수만큼 기사 번호를 생성하여 Redis 큐에 푸시합니다.
      for i in $( seq 1 $SCRAP_TARGET_CNT )
      do
          # 기사 번호를 계산하고 Redis 리스트 'scrap_queue'에 푸시합니다.
          redis-cli lpush scrap_queue "$SCRAP_URL$((START_ARTICLE_IDX - i + 1))" > /dev/null
      done
      
      # URL 큐 생성 완료 메시지를 출력합니다.
      echo "url 큐 생성 완료"
      
      # Redis 큐가 비어있지 않은 동안 반복합니다.
      while [ $(redis-cli llen scrap_queue) -ne 0 ]
      do
          # 현재 실행 중인 'consumer.sh' 프로세스 수를 확인합니다.
          current_processes=$(pgrep -fc "consumer.sh")
          echo "현재 사용 프로세스 수 : $current_processes"
          
          # 현재 실행 중인 프로세스 수가 최대 프로세스 수보다 적으면 새 프로세스를 실행합니다.
          if [ $current_processes -lt $MAX_PROCESS ]
          then
              echo "새로운 프로세스 할당"
              # 'consumer.sh' 스크립트를 백그라운드에서 실행합니다.
              ./consumer.sh &
              # 0.05초 대기합니다.
      		# 이는 너무 빠른 속도로 프로세스를 생성하지 않기 위함입니다.
              sleep 0.05
          else
              # 최대 프로세스 수에 도달하면 대기합니다.
              echo "사용가능한 프로세스를 모두 사용중입니다. 기다리세요.."
              while [ $(pgrep -fc "consumer.sh") -ge $MAX_PROCESS ]
              do
                  continue
              done
          fi
          echo ""
      done
      
      # 모든 백그라운드 작업이 완료될 때까지 대기합니다.
      wait
      
      # 스크래핑 완료 메시지를 출력합니다.
      echo "스크래핑 완료"
      
      # 스크립트를 종료합니다.
      exit 0
      
      
    2. 소비자 스크립트(’ consumer.sh ’)

      쉘스크립트 생성 후 스크립트를 끼워넣는다.

      소비자 스크립트는 Queue을 꺼내고, 해당 URL의 이미지를 생성하여 적절한 디렉토리에 저장한다.

      #!/bin/bash
      # Redis 리스트 'scrap_queue'에서 다음 URL을 가져옵니다.
      CURRENT_URL=$(redis-cli rpop scrap_queue)
      
      # 가져온 URL과 함께 스크래핑 시작 메시지를 출력합니다.
      echo "$CURRENT_URL" "스크래핑 시작"
      
      # URL에서 기사 번호를 추출합니다. (URL의 끝자리가 숫자일 경우를 가정)
      article_number=$(echo $CURRENT_URL | sed 's/.*\\/\\([0-9]\\+\\)$/\\1/')
      
      # 결과를 저장할 디렉토리 경로를 초기화합니다.
      dir_path="result/"
      
      # 기사 번호의 마지막 자리를 제외한 각 자리 숫자를 반복합니다.
      for (( i=0; i<${#article_number}-1; i++ ))
      do
      	# 현재 자리 숫자를 추출합니다.
      	digit="${article_number:i:1}"
      	# 디렉토리 경로에 현재 자리 숫자를 추가합니다.
      	dir_path="${dir_path}${digit}/"
      	# 디렉토리가 존재하지 않으면 생성합니다.
      	if [ ! -d "$dir_path" ]
      	then
      		mkdir -p "$dir_path"
      	fi
      done
      
      # wkhtmltoimage 명령어를 사용하여 URL의 스크린샷을 지정한 경로에 저장합니다.
      # 출력은 무시하고, 백그라운드에서 실행합니다.
      wkhtmltoimage "$CURRENT_URL" "${dir_path}$article_number.jpg" >/dev/null 2>&1 &
      
      # 백그라운드 프로세스의 PID를 저장합니다.
      pid=$!
      
      # 백그라운드 프로세스가 종료될 때까지 기다립니다.
      wait $pid
      
      # 스크립트를 종료합니다.
      exit 0
      
      


    실행 방법

    1. 쉘 스크립트를 생성

      vi producer.sh
      vi consumer.sh
      

      → vi 편집기로 스크립트 생성후 코드 삽입 후 esc + :wq 로 저장.

    2. 스크립트에 실행 권한을 부여

    chmod +x producer.sh
    chmod +x consumer.sh
    
    1. 생성자 스크립트 실행
    ./producer.sh
    


    결과확인

    스크립트가 실행되는 동안 result 디렉토리에 소비자 스크립트(consumer.sh)의 결과가 저장됩니다. 각 소비자 스크립트는 개별 URL을 처리하고, 결과를 파일로 저장합니다.

    $ ls -R result 로 스크랩이미지를 편하게 확인 가능합니다.