Як витягти список тем із Subreddit за допомогою Bash

Reddit пропонує канали JSON для кожного subreddit. Ось як створити сценарій Bash, який завантажує та аналізує список публікацій із будь-якого субредиту, який вам подобається. Це лише одна річ, яку ви можете зробити за допомогою каналів JSON Reddit.

Встановлення Curl і JQ

Ми збираємося використовувати curl для отримання каналу JSON з Reddit, а jq — для аналізу даних JSON і витягування потрібних полів із результатів. Встановіть ці дві залежності за допомогою apt-get в Ubuntu та інших дистрибутивах Linux на базі Debian. В інших дистрибутивах Linux замість цього використовуйте інструмент керування пакетами свого дистрибутива.

sudo apt-get install curl jq

Отримати деякі дані JSON з Reddit

Давайте подивимося, як виглядає канал даних. Використовуйте curl, щоб отримати останні повідомлення з Помірно Цікаво subreddit:

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

Зверніть увагу на те, як параметри, використані перед URL-адресою: -s, змушують curl працювати в беззвучному режимі, тому ми не бачимо жодного результату, крім даних із серверів Reddit. Наступний параметр і наступний параметр — «Приклад скребка reddit» , встановлюють користувацький рядок агента користувача, який допомагає Reddit ідентифікувати службу, яка отримує доступ до їхніх даних. Сервери Reddit API застосовують обмеження швидкості на основі рядка агента користувача. Встановлення спеціального значення змусить Reddit сегментувати наше обмеження швидкості від інших абонентів і зменшить ймовірність того, що ми отримаємо помилку HTTP 429 Rate Limit Exceeded.

  Як використовувати відео «картинка в картинці» (PiP) на iPad

Результат повинен заповнити вікно терміналу і виглядати приблизно так:

У вихідних даних є багато полів, але все, що нас цікавить, це назва, постійне посилання та URL-адреса. Ви можете побачити вичерпний список типів та їх полів на сторінці документації API Reddit: https://github.com/reddit-archive/reddit/wiki/JSON

Вилучення даних з виводу JSON

Ми хочемо витягти заголовок, постійне посилання та URL-адресу з вихідних даних і зберегти їх у файлі з роздільниками табуляції. Ми можемо використовувати інструменти обробки тексту, такі як sed і grep, але в нашому розпорядженні є інший інструмент, який розуміє структури даних JSON, який називається jq. Для нашої першої спроби давайте використаємо його для красивого друку та кольорового кодування результату. Ми будемо використовувати той самий виклик, що й раніше, але цього разу передайте вихід через jq та доручіть йому проаналізувати та надрукувати дані JSON.

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

Зверніть увагу на крапку після команди. Цей вираз просто аналізує вхідні дані та друкує їх як є. Результат виглядає добре відформатованим і кольоровим:

Давайте розглянемо структуру даних JSON, які ми отримуємо від Reddit. Кореневим результатом є об’єкт, який містить дві властивості: тип і дані. Останній має властивість під назвою дочірні, яка включає в себе масив публікацій у цьому субреддіті.

Кожен елемент масиву є об’єктом, який також містить два поля, які називаються типом і даними. Властивості, які ми хочемо отримати, знаходяться в об’єкті даних. jq очікує вираз, який можна застосувати до вхідних даних, і видає потрібний результат. Він повинен описувати вміст у термінах їхньої ієрархії та належності до масиву, а також як дані мають бути перетворені. Давайте знову запустимо всю команду з правильним виразом:

curl -s -A “reddit scraper example” https://www.reddit.com/r/MildlyInteresting.json | jq ‘.data.children | .[] | .data.title, .data.url, .data.permalink’

Вихідні дані показують назву, URL-адресу та постійне посилання, кожен у окремому рядку:

  Як вручну керувати вентиляторами вашого Mac

Давайте зануримося в команду 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

Цей сценарій спершу перевірить, чи ввів користувач ім’я subreddit. Якщо ні, він завершується з повідомленням про помилку та ненульовим кодом повернення.

Далі він збереже перший аргумент як ім’я subreddit і створить ім’я файлу з датою, куди буде збережений результат.

  Що таке стек фокусування?

Дія починається, коли curl викликається зі користувацьким заголовком і URL-адресою субреддіта, який потрібно скребти. Вихідні дані передаються до jq, де вони аналізуються та зводяться до трьох полів: заголовок, URL-адреса та постійне посилання. Ці рядки читаються по черзі й зберігаються у змінній за допомогою команди read, все це всередині циклу while, який продовжуватиметься, доки не буде більше рядків для читання. Останній рядок внутрішнього блоку while повторює три поля, розділені символом табуляції, а потім передає його через команду tr, щоб можна було видалити подвійні лапки. Потім результат додається до файлу.

Перш ніж ми зможемо виконати цей сценарій, ми повинні переконатися, що йому надано дозволи на виконання. Використовуйте команду chmod, щоб застосувати ці дозволи до файлу:

chmod u+x scrape-reddit.sh

І, нарешті, виконайте сценарій з іменем subreddit:

./scrape-reddit.sh MildlyInteresting

Вихідний файл створюється в тому самому каталозі, а його вміст буде виглядати приблизно так:

Кожен рядок містить три поля, які ми шукаємо, розділені символом табуляції.

Ідучи далі

Reddit — це золота копальня цікавого вмісту та медіа, і до всього цього легко отримати доступ за допомогою його JSON API. Тепер, коли у вас є спосіб отримати доступ до цих даних та обробити результати, ви можете робити такі дії:

Візьміть останні заголовки з /r/WorldNews і надішліть їх на свій робочий стіл за допомогою сповістити-відіслати
Інтегруйте найкращі жарти з /r/DadJokes у свою систему Message-Of-The-Day
Отримайте найкраще сьогодні зображення з /r/aww і зробіть його фоном робочого столу

Все це можливо за допомогою наданих даних та інструментів, які є у вашій системі. Щасливого злому!