So kratzen Sie eine Liste von Themen aus einem Subreddit mit Bash

Reddit bietet JSON-Feeds für jedes Subreddit. So erstellen Sie ein Bash-Skript, das eine Liste von Posts von jedem beliebigen Subreddit herunterlädt und analysiert. Dies ist nur eine Sache, die Sie mit den JSON-Feeds von Reddit tun können.

Installieren von Curl und JQ

Wir werden curl verwenden, um den JSON-Feed von Reddit und jq abzurufen, um die JSON-Daten zu analysieren und die gewünschten Felder aus den Ergebnissen zu extrahieren. Installieren Sie diese beiden Abhängigkeiten mit apt-get auf Ubuntu und anderen Debian-basierten Linux-Distributionen. Verwenden Sie bei anderen Linux-Distributionen stattdessen das Paketverwaltungstool Ihrer Distribution.

sudo apt-get install curl jq

Einige JSON-Daten von Reddit abrufen

Sehen wir uns an, wie der Datenfeed aussieht. Verwenden Sie curl, um die neuesten Beiträge von der abzurufen LeichtInteressant Subreddit:

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

Beachten Sie, wie die vor der URL verwendeten Optionen: -s erzwingt, dass curl im Silent-Modus ausgeführt wird, sodass wir keine Ausgabe sehen, außer den Daten von Reddits Servern. Die nächste Option und der darauf folgende Parameter, -A „reddit Scraper example“ , legen eine benutzerdefinierte Benutzeragentenzeichenfolge fest, die Reddit hilft, den Dienst zu identifizieren, der auf seine Daten zugreift. Die Reddit-API-Server wenden Ratenlimits basierend auf der Zeichenfolge des Benutzeragenten an. Wenn Sie einen benutzerdefinierten Wert festlegen, wird Reddit unser Ratenlimit von anderen Anrufern wegsegmentieren und die Wahrscheinlichkeit verringern, dass wir einen HTTP 429 Rate Limit Exceeded-Fehler erhalten.

Die Ausgabe sollte das Terminalfenster ausfüllen und etwa so aussehen:

Es gibt viele Felder in den Ausgabedaten, aber alles was uns interessiert sind Titel, Permalink und URL. Eine vollständige Liste der Typen und ihrer Felder finden Sie auf der API-Dokumentationsseite von Reddit: https://github.com/reddit-archive/reddit/wiki/JSON

  So erstellen Sie Widgets mit transparentem Hintergrund auf dem iPhone

Extrahieren von Daten aus der JSON-Ausgabe

Wir möchten Titel, Permalink und URL aus den Ausgabedaten extrahieren und in einer tabulatorgetrennten Datei speichern. Wir können Textverarbeitungstools wie sed und grep verwenden, aber wir haben ein anderes Tool zur Verfügung, das JSON-Datenstrukturen versteht, genannt jq . Für unseren ersten Versuch verwenden wir es, um die Ausgabe hübsch zu drucken und zu farbkodieren. Wir verwenden denselben Aufruf wie zuvor, aber diesmal leiten wir die Ausgabe über jq weiter und weisen sie an, die JSON-Daten zu analysieren und zu drucken.

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

Beachten Sie den Punkt, der dem Befehl folgt. Dieser Ausdruck analysiert einfach die Eingabe und gibt sie unverändert aus. Die Ausgabe sieht schön formatiert und farbcodiert aus:

Untersuchen wir die Struktur der JSON-Daten, die wir von Reddit zurückbekommen. Das Root-Ergebnis ist ein Objekt, das zwei Eigenschaften enthält: kind und data. Letztere enthält eine Eigenschaft namens children, die ein Array von Beiträgen zu diesem Subreddit enthält.

Jedes Element im Array ist ein Objekt, das auch zwei Felder namens kind und data enthält. Die Eigenschaften, die wir erfassen möchten, befinden sich im Datenobjekt. jq erwartet einen Ausdruck, der auf die Eingabedaten angewendet werden kann und erzeugt die gewünschte Ausgabe. Es muss den Inhalt in Bezug auf seine Hierarchie und Zugehörigkeit zu einem Array beschreiben sowie die Art und Weise, wie die Daten transformiert werden sollen. Lassen Sie uns den gesamten Befehl noch einmal mit dem richtigen Ausdruck ausführen:

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

Die Ausgabe zeigt Titel, URL und Permalink jeweils in einer eigenen Zeile:

  So blockieren Sie die Tastenprotokollierung durch HP Audiotreiber auf Elitebooks

Lassen Sie uns in den jq-Befehl eintauchen, den wir aufgerufen haben:

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

Dieser Befehl enthält drei Ausdrücke, die durch zwei Pipe-Symbole getrennt sind. Die Ergebnisse jedes Ausdrucks werden zur weiteren Auswertung an den nächsten weitergegeben. Der erste Ausdruck filtert alles außer dem Array der Reddit-Auflistungen heraus. Diese Ausgabe wird in den zweiten Ausdruck geleitet und in ein Array gezwungen. Der dritte Ausdruck wirkt auf jedes Element im Array und extrahiert drei Eigenschaften. Weitere Informationen zu jq und seiner Ausdruckssyntax finden Sie in jqs offizielles Handbuch.

Alles in einem Skript zusammenfassen

Lassen Sie uns den API-Aufruf und die JSON-Nachbearbeitung in einem Skript zusammenfassen, das eine Datei mit den gewünschten Beiträgen generiert. Wir werden Unterstützung für das Abrufen von Beiträgen von jedem Subreddit hinzufügen, nicht nur /r/MildlyInteresting.

Öffnen Sie Ihren Editor und kopieren Sie den Inhalt dieses Snippets in eine Datei namens scratche-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

Dieses Skript prüft zunächst, ob der Benutzer einen Subreddit-Namen angegeben hat. Wenn nicht, wird es mit einer Fehlermeldung und einem Rückkehrcode ungleich Null beendet.

Als nächstes wird das erste Argument als Subreddit-Name gespeichert und ein Dateiname mit Datumsstempel erstellt, in dem die Ausgabe gespeichert wird.

Die Aktion beginnt, wenn curl mit einem benutzerdefinierten Header und der URL des zu kratzenden Subreddits aufgerufen wird. Die Ausgabe wird an jq geleitet, wo sie geparst und auf drei Felder reduziert wird: Titel, URL und Permalink. Diese Zeilen werden einzeln gelesen und mit dem read-Befehl in einer Variablen gespeichert, alles innerhalb einer while-Schleife, die so lange fortgesetzt wird, bis keine Zeilen mehr zu lesen sind. Die letzte Zeile des inneren while-Blocks gibt die drei Felder wieder, die durch ein Tabulatorzeichen getrennt sind, und leitet sie dann durch den tr-Befehl, damit die doppelten Anführungszeichen entfernt werden können. Die Ausgabe wird dann an eine Datei angehängt.

  So erstellen Sie ein iMessage-Profil auf iPhone und iPad

Bevor wir dieses Skript ausführen können, müssen wir sicherstellen, dass ihm Ausführungsberechtigungen erteilt wurden. Verwenden Sie den Befehl chmod, um diese Berechtigungen auf die Datei anzuwenden:

chmod u+x scrape-reddit.sh

Und schließlich führen Sie das Skript mit einem Subreddit-Namen aus:

./scrape-reddit.sh MildlyInteresting

Eine Ausgabedatei wird im selben Verzeichnis generiert und ihr Inhalt sieht ungefähr so ​​​​aus:

Jede Zeile enthält die drei Felder, nach denen wir suchen, getrennt durch ein Tabulatorzeichen.

Weitergehen

Reddit ist eine Goldmine interessanter Inhalte und Medien, auf die über die JSON-API leicht zugegriffen werden kann. Da Sie nun eine Möglichkeit haben, auf diese Daten zuzugreifen und die Ergebnisse zu verarbeiten, können Sie beispielsweise Folgendes tun:

Holen Sie sich die neuesten Schlagzeilen von /r/WorldNews und senden Sie sie mit . an Ihren Desktop benachrichtigen-senden
Integrieren Sie die besten Witze aus /r/DadJokes in die Message-Of-The-Day Ihres Systems
Holen Sie sich das beste Bild von heute aus /r/aww und machen Sie es zu Ihrem Desktop-Hintergrund

All dies ist mit den bereitgestellten Daten und den Tools, die Sie auf Ihrem System haben, möglich. Viel Spaß beim Hacken!