레딧은 각 하위 레딧에 대해 JSON 형식의 데이터 피드를 제공합니다. 이번 글에서는 특정 하위 레딧에서 게시물 목록을 다운로드하고, 그 내용을 분석하는 Bash 스크립트 작성법을 소개합니다. 이는 레딧 JSON 피드를 활용할 수 있는 여러 방법 중 하나일 뿐입니다.
Curl 및 JQ 설치
레딧에서 JSON 피드를 가져오고, JSON 데이터를 분석하여 원하는 정보만 추출하기 위해 `curl`과 `jq`를 사용할 것입니다. Ubuntu 및 기타 Debian 계열 Linux 배포판에서는 `apt-get` 명령을 사용하여 이 두 가지 종속성을 설치할 수 있습니다. 다른 Linux 배포판에서는 해당 배포판의 패키지 관리자를 사용하면 됩니다.
sudo apt-get install curl jq
레딧 JSON 데이터 가져오기
먼저 데이터 피드가 어떻게 구성되어 있는지 살펴보겠습니다. `curl` 명령어를 사용하여 최신 게시물을 가져와 보겠습니다. 예를 들어, 약간 흥미로운 하위 레딧을 대상으로 해보겠습니다.
curl -s -A “reddit scraper example” https://www.reddit.com/r/MildlyInteresting.json
여기서 `-s` 옵션은 자동 모드로 `curl`을 실행하여 데이터 외 다른 출력을 표시하지 않도록 합니다. `-A “reddit scraper example”` 매개변수는 레딧 서버에 접근하는 서비스가 무엇인지 식별하는 사용자 정의 사용자 에이전트 문자열을 설정합니다. 레딧 API 서버는 이 사용자 에이전트 문자열을 기반으로 속도 제한을 적용합니다. 사용자 정의 값을 설정하면 레딧 서버는 여러 호출자들을 구분할 수 있게 되어 HTTP 429 오류(“Rate Limit Exceeded”) 발생 가능성을 줄일 수 있습니다.
터미널 창에 표시되는 출력은 다음과 비슷해야 합니다.
출력 데이터에는 많은 필드가 있지만, 여기서 우리가 관심 있는 것은 제목(Title), 영구 링크(Permalink), URL입니다. 레딧 API 문서 페이지(https://github.com/reddit-archive/reddit/wiki/JSON)에서 데이터 타입 및 필드에 대한 자세한 설명을 확인할 수 있습니다.
JSON 출력에서 데이터 추출
이제 출력된 데이터에서 제목(Title), 영구 링크(Permalink), URL을 추출하여 탭으로 구분된 파일에 저장해보겠습니다. `sed`나 `grep` 같은 텍스트 처리 도구를 사용할 수도 있지만, 여기서는 JSON 데이터 구조를 이해하는 `jq`라는 도구를 사용하겠습니다. 먼저 `jq`를 사용하여 출력을 예쁘게 인쇄하고 색상으로 구분해 보겠습니다. 이전과 같은 명령어를 사용하되, 이번에는 출력을 `jq`로 파이프하여 JSON 데이터를 분석하고 인쇄하도록 하겠습니다.
curl -s -A “reddit scraper example” https://www.reddit.com/r/MildlyInteresting.json | jq .
명령 뒤에 오는 점(.)에 주목하세요. 이 표현식은 입력을 단순히 파싱하고 있는 그대로 출력합니다. 출력은 보기 좋게 포맷되고 색상으로 구분되어 표시될 것입니다.
레딧에서 반환된 JSON 데이터 구조를 살펴보겠습니다. 루트 결과는 `kind`와 `data`라는 두 가지 속성을 가진 객체입니다. `data` 속성은 해당 하위 레딧의 게시물 배열을 포함하는 `children` 속성을 가지고 있습니다.
배열의 각 항목은 `kind`와 `data`라는 두 개의 필드를 포함하는 객체입니다. 우리가 얻고자 하는 속성들은 이 `data` 객체 안에 있습니다. `jq`는 입력 데이터에 적용할 수 있는 표현식을 통해 원하는 출력을 생성합니다. 계층 구조 및 배열에 대한 멤버십 및 데이터 변환 방법을 지정해야 합니다. 올바른 표현식을 사용하여 전체 명령을 다시 실행해 보겠습니다.
curl -s -A “reddit scraper example” https://www.reddit.com/r/MildlyInteresting.json | jq ‘.data.children | .[] | .data.title, .data.url, .data.permalink’
이제 출력은 각 줄에 제목(Title), URL, 영구 링크(Permalink)를 표시합니다.
사용된 `jq` 명령을 살펴보겠습니다.
jq ‘.data.children | .[] | .data.title, .data.url, .data.permalink’
이 명령어는 두 개의 파이프 기호로 구분된 세 개의 표현식을 가지고 있습니다. 각 표현식의 결과는 추가 평가를 위해 다음 표현식으로 전달됩니다. 첫 번째 표현식은 레딧 목록 배열을 제외한 모든 것을 걸러냅니다. 이 출력은 배열로 강제 변환되는 두 번째 표현식으로 파이프됩니다. 세 번째 표현식은 배열의 각 요소에 작용하여 세 가지 속성을 추출합니다. `jq` 및 표현식 문법에 대한 자세한 내용은 jq의 공식 매뉴얼에서 확인할 수 있습니다.
스크립트로 통합하기
이제 API 호출과 JSON 처리 과정을 스크립트에 통합하여 원하는 게시물 정보가 담긴 파일을 만들어 보겠습니다. /r/MildlyInteresting뿐만 아니라 모든 하위 레딧에서 게시물을 가져올 수 있도록 지원을 추가할 것입니다.
텍스트 편집기를 열고 아래 스크립트를 `scrape-reddit.sh`라는 파일에 복사하세요.
#!/bin/bash if [ -z "$1" ] then echo "Please specify a subreddit" exit 1 fi SUBREDDIT=$1 NOW=$(date +"%m_%d_%y-%H_%M") OUTPUT_FILE="${SUBREDDIT}_${NOW}.txt" curl -s -A "bash-scrape-topics" https://www.reddit.com/r/${SUBREDDIT}.json | jq '.data.children | .[] | .data.title, .data.url, .data.permalink' | while read -r TITLE; do read -r URL read -r PERMALINK echo -e "${TITLE}t${URL}t${PERMALINK}" | tr --delete '"' >> ${OUTPUT_FILE} done
이 스크립트는 먼저 사용자가 하위 레딧 이름을 입력했는지 확인합니다. 입력하지 않은 경우 오류 메시지를 출력하고 0이 아닌 반환 코드로 종료됩니다.
다음으로, 첫 번째 인수를 하위 레딧 이름으로 저장하고, 출력 파일 이름에 현재 날짜 및 시간을 포함합니다.
스크립트의 핵심은 `curl`을 사용하여 사용자 정의 헤더와 함께 지정된 하위 레딧 URL에서 데이터를 가져오는 것입니다. 그 출력은 `jq`로 전달되어 필요한 데이터 (제목, URL, 영구 링크)를 추출합니다. 이 데이터는 한 번에 한 줄씩 읽혀 while 루프 내에서 변수에 저장됩니다. 루프 내 마지막 줄에서는 탭 문자로 구분된 세 개의 필드를 출력하고, 큰따옴표를 제거합니다. 그런 다음 이 출력은 파일에 추가됩니다.
이 스크립트를 실행하기 전에 실행 권한을 부여해야 합니다. `chmod` 명령을 사용하여 다음과 같이 파일에 실행 권한을 부여합니다.
chmod u+x scrape-reddit.sh
마지막으로, 하위 레딧 이름을 인수로 사용하여 스크립트를 실행합니다.
./scrape-reddit.sh MildlyInteresting
출력 파일은 스크립트와 같은 디렉토리에 생성되며, 파일 내용은 다음과 같습니다.
각 줄은 탭 문자로 구분된 세 개의 필드를 포함하고 있습니다.
더 나아가기
레딧은 흥미로운 콘텐츠와 미디어의 보고이며, JSON API를 통해 쉽게 접근할 수 있습니다. 이제 데이터를 가져오고 처리할 수 있게 되었으므로, 다음과 같은 일들을 해볼 수 있습니다.
- /r/WorldNews에서 최신 헤드라인을 가져와 notify-send를 사용하여 데스크톱 알림으로 표시합니다.
- /r/DadJokes에서 가장 인기 있는 아재 개그를 가져와 오늘의 메시지에 통합합니다.
- /r/aww에서 가장 귀여운 사진을 가져와 바탕 화면 배경으로 설정합니다.
제공된 데이터와 시스템에 있는 도구를 활용하여 이 모든 것이 가능합니다. 즐거운 코딩하세요!