Redis 설치 및 실행
스크립트는 Redis 서버를 사용하여 큐를 관리합니다. 따라서 Redis 서버가 설치되어 있어야 합니다. 설치 및 실행 방법은 다음과 같습니다:
sudo apt update
sudo apt install redis -y
sudo systemctl start redis
→ Redis가 실행 중인지 확인. “PONG” 나오면 제대로 설치완료.
redis-cli ping
wkhtmltoimage 설치
URL의 이미지를 생성하기 위해 ‘wkhtmltoimage’ 라이브러리가 필요합니다.
sudo apt install wkhtmltopdf -y
생성자 스크립트(’ 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
소비자 스크립트(’ 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
쉘 스크립트를 생성
vi producer.sh
vi consumer.sh
→ vi 편집기로 스크립트 생성후 코드 삽입 후 esc + :wq 로 저장.
스크립트에 실행 권한을 부여
chmod +x producer.sh
chmod +x consumer.sh
./producer.sh
스크립트가 실행되는 동안 result 디렉토리에 소비자 스크립트(consumer.sh)의 결과가 저장됩니다. 각 소비자 스크립트는 개별 URL을 처리하고, 결과를 파일로 저장합니다.
$ ls -R result 로 스크랩이미지를 편하게 확인 가능합니다.