Comment gratter une liste de sujets à partir d’un sous-reddit à l’aide de Bash

Reddit propose des flux JSON pour chaque sous-reddit. Voici comment créer un script Bash qui télécharge et analyse une liste de publications à partir de n’importe quel sous-programme que vous aimez. Ce n’est qu’une chose que vous pouvez faire avec les flux JSON de Reddit.

Installation de Curl et JQ

Nous allons utiliser curl pour récupérer le flux JSON de Reddit et jq pour analyser les données JSON et extraire les champs que nous voulons des résultats. Installez ces deux dépendances en utilisant apt-get sur Ubuntu et d’autres distributions Linux basées sur Debian. Sur les autres distributions Linux, utilisez plutôt l’outil de gestion des packages de votre distribution.

sudo apt-get install curl jq

Récupérer des données JSON à partir de Reddit

Voyons à quoi ressemble le flux de données. Utilisez curl pour récupérer les derniers messages du Légèrement intéressant sous-reddit:

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

Notez comment les options utilisées avant l’URL: -s forcent curl à s’exécuter en mode silencieux afin que nous ne voyions aucune sortie, à l’exception des données des serveurs de Reddit. L’option suivante et le paramètre qui suit, -Un «exemple de grattoir reddit», définit une chaîne d’agent utilisateur personnalisée qui aide Reddit à identifier le service accédant à leurs données. Les serveurs API Reddit appliquent des limites de taux basées sur la chaîne de l’agent utilisateur. La définition d’une valeur personnalisée amènera Reddit à segmenter notre limite de débit loin des autres appelants et réduira le risque d’obtenir une erreur de dépassement de limite de débit HTTP 429.

La sortie devrait remplir la fenêtre du terminal et ressembler à ceci:

Il y a beaucoup de champs dans les données de sortie, mais tout ce qui nous intéresse sont le titre, le lien permanent et l’URL. Vous pouvez voir une liste exhaustive des types et de leurs champs sur la page de documentation de l’API de Reddit: https://github.com/reddit-archive/reddit/wiki/JSON

Extraction de données à partir de la sortie JSON

Nous voulons extraire le titre, le lien permanent et l’URL des données de sortie et les enregistrer dans un fichier délimité par des tabulations. Nous pouvons utiliser des outils de traitement de texte comme sed et grep, mais nous avons un autre outil à notre disposition qui comprend les structures de données JSON, appelé jq. Pour notre première tentative, utilisons-le pour joliment imprimer et coder en couleur la sortie. Nous utiliserons le même appel que précédemment, mais cette fois, dirigez la sortie via jq et demandez-lui d’analyser et d’imprimer les données JSON.

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

Notez la période qui suit la commande. Cette expression analyse simplement l’entrée et l’imprime telle quelle. La sortie semble bien formatée et codée par couleur:

Extraire les données du JSON d'un sous-redit dans Bash

Examinons la structure des données JSON que nous récupérons de Reddit. Le résultat racine est un objet qui contient deux propriétés: kind et data. Ce dernier possède une propriété appelée children, qui comprend un tableau de publications dans ce sous-reddit.

Chaque élément du tableau est un objet qui contient également deux champs appelés kind et data. Les propriétés que nous voulons récupérer se trouvent dans l’objet de données. jq attend une expression qui peut être appliquée aux données d’entrée et produit la sortie souhaitée. Il doit décrire le contenu en termes de hiérarchie et d’appartenance à un tableau, ainsi que la manière dont les données doivent être transformées. Exécutons à nouveau toute la commande avec l’expression correcte:

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

La sortie affiche le titre, l’URL et le lien permanent chacun sur leur propre ligne:

Analyser le contenu d'un sous-répertoire à partir de la ligne de commande Linux

Plongeons dans la commande jq que nous avons appelée:

jq ‘.data.children | .[] | .data.title, .data.url, .data.permalink’

Il y a trois expressions dans cette commande séparées par deux symboles de tuyau. Les résultats de chaque expression sont transmis à la suivante pour une évaluation plus approfondie. La première expression filtre tout sauf le tableau des listes Reddit. Cette sortie est redirigée vers la deuxième expression et forcée dans un tableau. La troisième expression agit sur chaque élément du tableau et extrait trois propriétés. Vous trouverez plus d’informations sur jq et sa syntaxe d’expression dans manuel officiel de jq.

Tout rassembler dans un script

Mettons l’appel API et le post-traitement JSON ensemble dans un script qui générera un fichier avec les publications souhaitées. Nous ajouterons la prise en charge de la récupération des messages depuis n’importe quel sous-répertoire, pas seulement / r / MildlyInteresting.

Ouvrez votre éditeur et copiez le contenu de cet extrait de code dans un fichier appelé 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

Ce script vérifiera d’abord si l’utilisateur a fourni un nom de sous-redit. Sinon, il quitte avec un message d’erreur et un code de retour différent de zéro.

Ensuite, il stockera le premier argument en tant que nom de sous-redit et construira un nom de fichier horodaté où la sortie sera enregistrée.

L’action commence lorsque curl est appelé avec un en-tête personnalisé et l’URL du sous-répertoire à gratter. La sortie est redirigée vers jq où elle est analysée et réduite à trois champs: Titre, URL et Permalien. Ces lignes sont lues, une à la fois, et enregistrées dans une variable à l’aide de la commande read, toutes à l’intérieur d’une boucle while, qui se poursuivra jusqu’à ce qu’il n’y ait plus de lignes à lire. La dernière ligne du bloc while interne fait écho aux trois champs, délimités par un caractère de tabulation, puis la redirige vers la commande tr afin que les guillemets puissent être supprimés. La sortie est ensuite ajoutée à un fichier.

Avant de pouvoir exécuter ce script, nous devons nous assurer qu’il dispose des autorisations d’exécution. Utilisez la commande chmod pour appliquer ces autorisations au fichier:

chmod u+x scrape-reddit.sh

Et, enfin, exécutez le script avec un nom de sous-redit:

./scrape-reddit.sh MildlyInteresting

Un fichier de sortie est généré dans le même répertoire et son contenu ressemblera à ceci:

Grattez et affichez les sujets d'un sous-reddit dans Bash

Chaque ligne contient les trois champs que nous recherchons, séparés par un caractère de tabulation.

Aller plus loin

Reddit est une mine d’or de contenu et de médias intéressants, et tout est facilement accessible à l’aide de son API JSON. Maintenant que vous avez un moyen d’accéder à ces données et de traiter les résultats, vous pouvez faire des choses comme:

Récupérez les derniers titres de / r / WorldNews et envoyez-les sur votre bureau en utilisant notifier-envoyer
Intégrez les meilleures blagues de / r / DadJokes dans le Message-Of-The-Day de votre système
Obtenez la meilleure image d’aujourd’hui à partir de / r / aww et faites-en l’arrière-plan de votre bureau

Tout cela est possible en utilisant les données fournies et les outils dont vous disposez sur votre système. Bon piratage!