Bash를 사용하여 하위 레딧에서 주제 목록을 스크랩하는 방법

Reddit은 각 하위 레딧에 대한 JSON 피드를 제공합니다. 다음은 원하는 하위 레딧에서 게시물 목록을 다운로드하고 구문 분석하는 Bash 스크립트를 만드는 방법입니다. 이것은 Reddit의 JSON 피드로 할 수 있는 일 중 하나일 뿐입니다.

Curl 및 JQ 설치

curl을 사용하여 Reddit 및 jq에서 JSON 피드를 가져와 JSON 데이터를 구문 분석하고 결과에서 원하는 필드를 추출합니다. Ubuntu 및 기타 Debian 기반 Linux 배포에서 apt-get을 사용하여 이 두 종속성을 설치합니다. 다른 Linux 배포판에서는 배포판의 패키지 관리 도구를 대신 사용하십시오.

sudo apt-get install curl jq

Reddit에서 일부 JSON 데이터 가져오기

데이터 피드가 어떻게 생겼는지 봅시다. curl을 사용하여 최신 게시물을 가져옵니다. 약간 흥미롭다 하위 레딧:

curl -s -A “reddit scraper example” https://www.reddit.com/r/MildlyInteresting.json

URL: -s 앞에 사용된 옵션이 어떻게 자동 모드에서 curl을 실행하여 Reddit 서버의 데이터를 제외하고는 어떤 출력도 볼 수 없도록 하는 방법에 유의하십시오. 다음 옵션과 -A “reddit scraper example” 매개변수는 Reddit이 데이터에 액세스하는 서비스를 식별하는 데 도움이 되는 사용자 지정 사용자 에이전트 문자열을 설정합니다. Reddit API 서버는 사용자 에이전트 문자열을 기반으로 속도 제한을 적용합니다. 사용자 지정 값을 설정하면 Reddit에서 다른 호출자와 속도 제한을 구분하고 HTTP 429 Rate Limit Exceeded 오류가 발생할 가능성을 줄입니다.

출력은 터미널 창을 채우고 다음과 같아야 합니다.

출력 데이터에는 많은 필드가 있지만 우리가 관심을 갖는 것은 제목, 영구 링크 및 URL뿐입니다. Reddit의 API 문서 페이지에서 유형 및 해당 필드의 전체 목록을 볼 수 있습니다. https://github.com/reddit-archive/reddit/wiki/JSON

JSON 출력에서 ​​데이터 추출

출력 데이터에서 Title, Permalink 및 URL을 추출하여 탭으로 구분된 파일에 저장하려고 합니다. sed 및 grep 과 같은 텍스트 처리 도구를 사용할 수 있지만 jq 라는 JSON 데이터 구조를 이해하는 또 다른 도구가 있습니다. 첫 번째 시도에서는 출력물을 예쁘게 인쇄하고 색상 코딩하는 데 사용하겠습니다. 이전과 동일한 호출을 사용하지만 이번에는 출력을 jq를 통해 파이프하고 JSON 데이터를 구문 분석하고 인쇄하도록 지시합니다.

curl -s -A “reddit scraper example” https://www.reddit.com/r/MildlyInteresting.json | jq .

명령 뒤에 오는 마침표에 유의하십시오. 이 표현식은 단순히 입력을 구문 분석하고 있는 그대로 인쇄합니다. 출력은 보기 좋게 형식이 지정되고 색상으로 구분됩니다.

  "ICYMI"는 무엇을 의미하며 어떻게 사용합니까?

Reddit에서 반환된 JSON 데이터의 구조를 살펴보겠습니다. 루트 결과는 종류와 데이터라는 두 가지 속성을 포함하는 개체입니다. 후자는 이 하위 레딧에 대한 게시물 배열을 포함하는 children이라는 속성을 보유합니다.

배열의 각 항목은 종류와 데이터라는 두 개의 필드도 포함하는 개체입니다. 잡고자 하는 속성은 데이터 개체에 있습니다. 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’

이 명령에는 두 개의 파이프 기호로 구분된 세 개의 표현식이 있습니다. 각 표현식의 결과는 추가 평가를 위해 다음 표현식으로 전달됩니다. 첫 번째 표현식은 Reddit 목록 배열을 제외한 모든 것을 필터링합니다. 이 출력은 두 번째 표현식으로 파이프되어 배열로 강제 실행됩니다. 세 번째 표현식은 배열의 각 요소에 작용하고 세 가지 속성을 추출합니다. 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이 아닌 반환 코드와 함께 종료됩니다.

  Linux에서 바인드 마운트 및 심볼릭 링크를 사용하는 방법

다음으로, 첫 번째 인수를 하위 레딧 이름으로 저장하고 출력이 저장될 날짜 스탬프 파일 이름을 만듭니다.

작업은 사용자 정의 헤더와 스크랩할 하위 레딧의 URL과 함께 curl이 호출될 때 시작됩니다. 출력은 구문 분석되고 Title, URL 및 Permalink의 세 가지 필드로 축소되는 jq로 파이프됩니다. 이 줄은 한 번에 하나씩 읽혀지고 더 이상 읽을 줄이 없을 때까지 계속되는 while 루프 내에서 read 명령을 사용하여 변수에 저장됩니다. 내부 while 블록의 마지막 줄은 탭 문자로 구분된 세 개의 필드를 에코한 다음 큰따옴표를 제거할 수 있도록 tr 명령을 통해 파이프합니다. 그런 다음 출력이 파일에 추가됩니다.

이 스크립트를 실행하기 전에 실행 권한이 부여되었는지 확인해야 합니다. chmod 명령을 사용하여 다음 권한을 파일에 적용합니다.

chmod u+x scrape-reddit.sh

마지막으로 하위 레딧 이름으로 스크립트를 실행합니다.

./scrape-reddit.sh MildlyInteresting

출력 파일은 동일한 디렉토리에 생성되며 그 내용은 다음과 같습니다.

각 줄에는 탭 문자를 사용하여 구분된 3개의 필드가 포함되어 있습니다.

더 나아가

Reddit은 흥미로운 콘텐츠와 미디어의 금광이며 JSON API를 사용하여 모두 쉽게 액세스할 수 있습니다. 이제 이 데이터에 액세스하고 결과를 처리할 수 있으므로 다음과 같은 작업을 수행할 수 있습니다.

/r/WorldNews에서 최신 헤드라인을 가져와 다음을 사용하여 데스크탑으로 보냅니다. 알림 보내기
/r/DadJokes의 최고의 농담을 시스템의 오늘의 메시지에 통합하십시오.
/r/aww에서 오늘의 최고의 사진을 가져와 바탕 화면 배경으로 만드십시오.

이 모든 것은 제공된 데이터와 시스템에 있는 도구를 사용하여 가능합니다. 즐거운 해킹!