먼저 이건 철저하게 배포용을 위해서 만든 기술이 아니라 개인 소장용이라는 점을 명백하게 말하겠다.

어떤 사이트를 가 봤는데 맘에 드는 사진이나 그림들이 연달아 나열된 경우가 많다. 로딩도 해야하고 일일이 클릭도 하는게 귀찮아서 그 사진들을 다 다운받아서 만화책 보는 프로그램으로 쭉 보고 싶을때가 있다.

그렇다! 귀찮은 것이다. 귀찮으면 DRY (Don't Repeat Yourself:같은 일을 반복하지 말고 반복하는 일은 전부 컴퓨터에게 맡겨라) 원칙에 따라서 개발자 본능이 꿈틀거린다.

개발자의 종특중 하나는 일일이 눌러서 다운받는게 3시간 걸리는 작업이라도, 개발로 편하게 스크립트 짜는게 6시간이 걸려도 후자를 택하는 종족이기 때문이다. (다만 한번 한 작업은 다음에 할 때 무지하게 빨라진다는 장점이 있다)

이제 부터는 철저하게 시나리오다. 내가 이런다는 것이 절대 아니다.

어느 사이트에 갔더니 만화가 올려져 있다. '엇! 이런 횡재를!!' 게다가 사이트를 보니 소스를 볼 수가 있는 것이다. 1화를 누르고 소스보기를 통해서 그 소스를 happy01.html 로 저장했다. 이제 이걸

$ get-picture.sh happy01.html 1

하면 내가 원하는 그림 파일들이 01-01.png 나 01-01.jpg 이런 형식으로 쭈욱 저장된다. 앞에 01, 02 이런식으로 저장하는건 나중에 만화책 뷰어가 파일 순서를 헷갈리기 때문에 저런 형식으로 저장해줘야 한다.

개별 설명을 하자면 먼저 스크립트다.

#!/bin/bash argc=$# HTML=$1 PART=$2 NUM="1" FILENAME="" if [ $argc -eq 2 ] then cat "${HTML}" | sed -E -f newline.sed | grep -E 'https://www.avsnoop' | \ awk '{print $1}' |while read url ; \ do FILENAME=$(printf "%02d-%02d.%s" "$PART" "$NUM" "`echo "${url}" | sed -E 's/^.*(png|jpg)/\1/'`");\ echo "downloading.. ${url}" ; curl -o "${FILENAME}" "${url}" ;NUM=$[$NUM +1] ;done else echo "Usage: get-picture.sh [HTML name] [Part Number]" fi

위 내용을 긁어서 쓸때는 \개행문자 콤보를 지우고 한줄로 만들어서 쓰는게 좋다. (보기 안좋아서 이리 처리함)

매개변수가 2개가 안되면 사용법을 출력하고 종료하고 매개 변수가 첫번째 html 파일 이름 과 몇 화로 저장할것인지를 지정해주면 동작한다.

cat "${HTML}" 을 통해서 HTML 의 내용을 가지고 오고 그 내용을 sed 에게 넘겨줍니다.

sed 는 스트림 에디터 라고 하는데 보통 넘겨 받은 데이타에서 특정 패턴을 찾아서 지운다던가 패턴을 치환하는 용도로 많이 쓰인다. -E 옵션은 정규표현식을 처리한다는 것이고 -f 는 파일을 읽어서 처리한다는 뜻이다. 보통은 파일 처리를 안하지만 's/A/B/g' 와 같이 치환한다는 가정을 할 때 B 에 개행문자를 포함시켜서 치환이 command line 에서는 적용이 안된다.

newline.sed 를 보면

s/(https:\/\/www\.avsnoop\.com\/files\/2015\/09\/04\/[^/]*\.)(png|jpg)/\
\1\2\
/g

와 같은 식으로 특정 패턴을 찾으면 그 패턴 앞뒤로 \n 개행문자를 넣어주는 치환을 가한다. 이렇게 하는 이유는 sed 명령어 다음에 이어지는 grep 명령이 라인단위로 동작하기 때문에 정해진 패턴을 줄단위로 출력하게 만들기 위해서다.

다만 위의 내용대로 하다가 안받아져서 확인해 봤더니 /2015/09/05 날짜로 바뀐게 발견되었다. 그렇다면 그 부분까지 정규표현식으로 바꿔주면 된다.

s/(https:\/\/www\.avsnoop\.com\/files\/2015\/09\/[0-9]+\/[^/]*\.)(png|jpg)/\
\1\2\
/g

awk 명령어는 굳이 안써도 될꺼 같은데 습관처럼 썼다. white space 을 구별지어서 조작하는 명령을 줄 수있다. '{print $1}' 이면 첫번째 컬럼을 출력하라는 구문이다.

while 문은 전에 구별된 (여기 예제에서는 www.avsnoop 으로 구분된 이미지 주소) 를 url 로 받아온다. 그리고 printf 문을 이용해서 저장될 파일이름을 FILENAME 에 저장시키고 sed 문을 또 이용해서 확장자를 지정해준다.

downloading.. ${url} 로 현재 어떤 이미지를 다운 받는지 알려주고 정해진 파일 이름으로 curl 을 이용해서 다운받는다.

curl 을 사용하는 이유는 wget 으로 안받아지는 것들이 받아지기 때문이다. 즉 curl 이 wget 의 상위 호환이라고 보면됨. 최근 curl 을 사용하는게 이유가 있어서 이다. 이제 wget 을 보낼때가 됐다.


+ Recent posts