Reddit biedt JSON-feeds voor elke subreddit. Hier leest u hoe u een Bash-script maakt dat een lijst met berichten downloadt en parseert van elke gewenste subreddit. Dit is slechts één ding dat u kunt doen met de JSON-feeds van Reddit.
Curl en JQ installeren
We gaan gebruiken curl
om de JSON-feed van Reddit en jq
om de JSON-gegevens te ontleden en de gewenste velden uit de resultaten te halen. Installeer deze twee afhankelijkheden met apt-get
op Ubuntu en andere op Debian gebaseerde Linux-distributies. Gebruik op andere Linux-distributies het hulpprogramma voor pakketbeheer van uw distributie.
sudo apt-get install curl jq
Haal wat JSON-gegevens op van Reddit
Laten we eens kijken hoe de datafeed eruitziet. Gebruik curl
om de laatste berichten van de MildlyInteresting-subreddit op te halen:
curl -s -A “reddit scraper example” https://www.reddit.com/r/MildlyInteresting.json
Merk op hoe de opties die vóór de URL werden gebruikt: -s
dwingt curl om in de stille modus te draaien, zodat we geen uitvoer zien, behalve de gegevens van de servers van Reddit. De volgende optie en de parameter die volgt, -A “reddit scraper example”
, stelt een aangepaste user-agentstring in die Reddit helpt bij het identificeren van de service die toegang heeft tot hun gegevens. De Reddit API-servers passen tarieflimieten toe op basis van de user-agentstring. Als u een aangepaste waarde instelt, segmenteert Reddit onze snelheidslimiet weg van andere bellers en wordt de kans verkleind dat we een HTTP 429 Rate Limit Exceeded-fout krijgen.
De uitvoer zou het terminalvenster moeten vullen en er ongeveer zo uit moeten zien:
Er zijn veel velden in de uitvoergegevens, maar we zijn alleen geïnteresseerd in Titel, Permalink en URL. Je kunt een uitgebreide lijst met typen en hun velden bekijken op de API-documentatiepagina van Reddit: https://github.com/reddit-archive/reddit/wiki/JSON
Gegevens extraheren uit de JSON-uitvoer
We willen Titel, Permalink en URL extraheren uit de uitvoergegevens en deze opslaan in een door tabs gescheiden bestand. We kunnen tekstverwerkingshulpmiddelen gebruiken zoals sed
en grep
, maar we hebben nog een tool tot onze beschikking die JSON-datastructuren begrijpt, genaamd jq
. Laten we het voor onze eerste poging gebruiken om de uitvoer mooi af te drukken en een kleurcode te geven. We gebruiken dezelfde aanroep als voorheen, maar deze keer leid je de uitvoer door jq
en instrueer het om de JSON-gegevens te parseren en af te drukken.
curl -s -A “reddit scraper example” https://www.reddit.com/r/MildlyInteresting.json | jq .
Let op de periode die volgt op de opdracht. Deze uitdrukking parseert eenvoudig de invoer en drukt deze af zoals hij is. De uitvoer ziet er mooi opgemaakt en kleurgecodeerd uit:
Laten we eens kijken naar de structuur van de JSON-gegevens die we terugkrijgen van Reddit. Het root-resultaat is een object dat twee eigenschappen bevat: soort en data. De laatste heeft een eigenschap genaamd children
, die een reeks berichten op deze subreddit bevat.
Elk item in de array is een object dat ook twee velden bevat met de naam soort en data. De eigenschappen die we willen pakken, bevinden zich in het data-object. jq
verwacht een uitdrukking die kan worden toegepast op de invoergegevens en de gewenste uitvoer produceert. Het moet de inhoud beschrijven in termen van hun hiërarchie en lidmaatschap van een array, evenals hoe de gegevens moeten worden getransformeerd. Laten we de hele opdracht opnieuw uitvoeren met de juiste uitdrukking:
curl -s -A “reddit scraper example” https://www.reddit.com/r/MildlyInteresting.json | jq ‘.data.children | .[] | .data.title, .data.url, .data.permalink’
De uitvoer toont Titel, URL en Permalink elk op hun eigen regel:
Laten we een duik nemen in de jq
commando dat we noemden:
jq ‘.data.children | .[] | .data.title, .data.url, .data.permalink’
Er zijn drie uitdrukkingen in dit commando, gescheiden door twee pijpsymbolen. De resultaten van elke uitdrukking worden voor verdere evaluatie aan de volgende doorgegeven. De eerste uitdrukking filtert alles uit behalve de reeks Reddit-vermeldingen. Deze uitvoer wordt doorgesluisd naar de tweede expressie en geforceerd in een array. De derde uitdrukking werkt op elk element in de array en extraheert drie eigenschappen. Meer informatie over jq
en de syntaxis van de expressie is te vinden in de officiële handleiding van jq.
Alles samenvoegen in een script
Laten we de API-oproep en de JSON-nabewerking samenvoegen in een script dat een bestand genereert met de berichten die we willen. We zullen ondersteuning toevoegen voor het ophalen van berichten van elke subreddit, niet alleen / r / MildlyInteresting.
Open je editor en kopieer de inhoud van dit fragment naar een bestand met de naam 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
Dit script zal eerst controleren of de gebruiker een subreddit-naam heeft opgegeven. Als dit niet het geval is, wordt het afgesloten met een foutbericht en een retourcode die niet gelijk is aan nul.
Vervolgens zal het het eerste argument opslaan als de subreddit-naam en een bestandsnaam met datumstempel opbouwen waar de uitvoer wordt opgeslagen.
De actie begint wanneer curl
wordt aangeroepen met een aangepaste header en de URL van de te schrapen subreddit. De output wordt doorgesluisd naar jq
waar het wordt geparseerd en teruggebracht tot drie velden: Titel, URL en Permalink. Deze regels worden één voor één gelezen en opgeslagen in een variabele met behulp van het leescommando, allemaal binnen een while-lus, die doorgaat totdat er geen regels meer zijn om te lezen. De laatste regel van het binnenste while-blok echoot de drie velden, gescheiden door een tab-teken, en leidt deze vervolgens door de tr
commando zodat de dubbele aanhalingstekens kunnen worden verwijderd. De uitvoer wordt vervolgens aan een bestand toegevoegd.
Voordat we dit script kunnen uitvoeren, moeten we ervoor zorgen dat het uitvoerrechten is verleend. Gebruik de chmod
opdracht om deze machtigingen op het bestand toe te passen:
chmod u+x scrape-reddit.sh
En, ten slotte, voer het script uit met een subreddit-naam:
./scrape-reddit.sh MildlyInteresting
Een uitvoerbestand wordt gegenereerd in dezelfde map en de inhoud zal er ongeveer zo uitzien:
Elke regel bevat de drie velden die we zoeken, gescheiden door een tab-teken.
Verder gaan
Reddit is een goudmijn aan interessante inhoud en media, en het is allemaal gemakkelijk toegankelijk met behulp van de JSON API. Nu u een manier heeft om toegang te krijgen tot deze gegevens en de resultaten te verwerken, kunt u dingen doen als:
- Grijp de laatste koppen van / r / WorldNews en stuur ze naar uw desktop met behulp van Notification-send
- Integreer de beste grappen van / r / DadJokes in de Message-Of-The-Day van uw systeem
- Haal de beste foto van vandaag uit / r / aww en maak er je bureaubladachtergrond van
Dit alles is mogelijk met behulp van de verstrekte gegevens en de tools die u op uw systeem hebt. Veel plezier met hacken!