Reddit poskytuje JSON kanály pro každý subreddit. Tento článek vám ukáže, jak vytvořit skript v Bashi, který stahuje a zpracovává seznam příspěvků z libovolného subredditu dle vašeho výběru. To je pouze jeden z mnoha způsobů, jak využít JSON kanály Redditu.
Instalace Curl a JQ
Pro stahování JSON dat z Redditu budeme potřebovat nástroj curl. Pro analýzu a extrahování potřebných informací z JSON dat použijeme jq. Tyto dva nástroje nainstalujeme pomocí správce balíčků apt-get na Ubuntu a dalších distribucích Linuxu založených na Debianu. U ostatních distribucí Linuxu použijte správce balíčků specifický pro vaši distribuci.
sudo apt-get install curl jq
Stažení JSON dat z Redditu
Podíváme se, jak vypadají data, která získáme. Pomocí curl načteme nejnovější příspěvky ze subredditu Mírně Zajímavé:
curl -s -A "příklad reddit scraperu" https://www.reddit.com/r/MildlyInteresting.json
Všimněte si parametrů před URL: -s zajistí, že curl poběží tiše a neuvidíme žádný výstup kromě dat ze serverů Reddit. Další parametr -A „příklad reddit scraperu“ nastavuje vlastní uživatelský agent, který pomůže Redditu identifikovat službu, která přistupuje k jejich datům. Servery Reddit API používají limity pro odesílání požadavků založené na uživatelském agentu. Nastavení vlastní hodnoty zajistí, že Reddit bude s naším limitem zacházet odděleně od ostatních, a tím se sníží pravděpodobnost, že dostaneme HTTP 429 Rate Limit Exceeded.
Výsledkem bude výpis v terminálu, který vypadá nějak takto:
Ve výstupních datech je spousta polí, nás však zajímá pouze Název, Trvalý odkaz a URL. Kompletní seznam typů a polí najdete v dokumentaci API Redditu: https://github.com/reddit-archive/reddit/wiki/JSON
Extrahování dat z JSON výstupu
Chceme z výstupu extrahovat název, trvalý odkaz a URL a uložit je do souboru odděleného tabulátory. Můžeme použít nástroje jako sed a grep, ale k dispozici je specializovaný nástroj pro práci s JSON daty – jq. Nejprve si zkusíme pomocí jq výstup formátovat a obarvit. Použijeme stejný příkaz jako předtím, ale tentokrát výstup propojíme s jq a dáme mu příkaz data analyzovat a vytisknout.
curl -s -A "příklad reddit scraperu" https://www.reddit.com/r/MildlyInteresting.json | jq .
Všimněte si tečky za příkazem. Tento výraz pouze analyzuje vstup a vypíše jej v nezměněné podobě. Výstup bude pěkně naformátovaný a barevně odlišený:
Pojďme se podívat na strukturu JSON dat, která získáváme z Redditu. Výsledkem je objekt, který obsahuje dvě vlastnosti: kind a data. Vlastnost data obsahuje další vlastnost children, která zahrnuje řadu příspěvků v daném subredditu.
Každá položka v poli je objekt, který opět obsahuje dvě pole kind a data. Vlastnosti, které chceme získat, se nacházejí v objektu data. jq očekává výraz, který se použije na vstupní data a vygeneruje požadovaný výstup. Tento výraz musí popisovat obsah z hlediska hierarchie a členství v poli a také transformaci dat. Spusťte znovu příkaz se správným výrazem:
curl -s -A "příklad reddit scraperu" https://www.reddit.com/r/MildlyInteresting.json | jq '.data.children | .[] | .data.title, .data.url, .data.permalink'
Výstup zobrazí název, URL a trvalý odkaz, každý na samostatném řádku:
Probereme příkaz jq, který jsme použili:
jq '.data.children | .[] | .data.title, .data.url, .data.permalink'
V tomto příkazu jsou tři výrazy oddělené dvěma znaky potrubí. Výsledky každého výrazu se předávají k dalšímu vyhodnocení. První výraz odfiltruje vše kromě pole příspěvků z Redditu. Výstup je předán do druhého výrazu a vynucen do pole. Třetí výraz zpracuje každý prvek v poli a extrahuje tři vlastnosti. Více informací o jq a jeho syntaxi naleznete v oficiální dokumentaci jq.
Sestavení skriptu
Vytvoříme skript, který sestaví volání API a následné zpracování JSON do celku a vygeneruje soubor s požadovanými příspěvky. Přidáme podporu pro stahování příspěvků z jakéhokoli subredditu, nejen /r/MildlyInteresting.
Otevřete textový editor a vložte do souboru s názvem scrape-reddit.sh tento kód:
#!/bin/bash if [ -z "$1" ] then echo "Zadejte název subredditu" 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
Skript nejprve zkontroluje, zda uživatel zadal název subredditu. Pokud ne, skript se ukončí s chybovou hláškou a návratovým kódem.
Poté uloží první argument jako název subredditu a vygeneruje název výstupního souboru s aktuálním datem a časem.
Samotná akce začne, když se zavolá curl s vlastní hlavičkou a URL subredditu, který se má zpracovat. Výstup je přesměrován do jq, který data analyzuje a redukuje na tři pole: Title, URL a Permalink. Tyto řádky se postupně čtou a ukládají do proměnné pomocí příkazu read v rámci smyčky while. Ta bude pokračovat, dokud budou k dispozici další řádky. Poslední řádek vnitřní smyčky while vypíše tři pole oddělená tabulátorem, poté pomocí příkazu tr odstraní dvojité uvozovky. Výstup je nakonec přidán do souboru.
Před spuštěním skriptu musíme nastavit příznak spustitelnosti. To provedeme příkazem chmod:
chmod u+x scrape-reddit.sh
Nakonec skript spustíme s názvem subredditu jako argument:
./scrape-reddit.sh MildlyInteresting
Výstupní soubor se vygeneruje ve stejném adresáři a jeho obsah bude vypadat přibližně takto:
Každý řádek obsahuje tři požadovaná pole oddělená tabulátory.
Další možnosti
Reddit je skvělým zdrojem zajímavého obsahu a médií. Díky JSON API jsou data snadno dostupná. Nyní, když máte možnost, jak se k těmto datům dostat a jak je zpracovat, můžete například:
Získat nejnovější titulky z /r/WorldNews a zobrazit je na ploše pomocí notify-send
Integrovat vtipy z /r/DadJokes do svého systému Message-Of-The-Day
Získat nejlepší obrázek dne z /r/aww a nastavit si ho jako pozadí plochy
To vše je možné díky dostupným datům a nástrojům, které máte v systému. Přejeme vám úspěšné hackování!