Bash Kullanarak Bir Alt Klasördeki Bir Konu Listesini Kazıma

Fatmawati Achmad Zaenuri/Shutterstock.com

Reddit, her subreddit için JSON yayınlarını sunar. İşte istediğiniz herhangi bir subreddit'teki yayınların listesini indiren ve ayrıştıran bir Bash betiğinin nasıl oluşturulacağı. Reddit'in JSON yayınları ile yapabileceğiniz tek şey bu.

Curl ve JQ’yu Takma

JSON yayınını jq almak için curl kullanacağız ve JSON verilerini ayrıştırmak ve sonuçlardan istediğimiz alanları çıkarmak için kullanacağız. Ubuntu'daki apt-get ve diğer Debian tabanlı Linux dağıtımlarını kullanarak bu iki bağımlılığı kurun. Diğer Linux dağıtımlarında, dağıtımınızın paket yönetimi aracını kullanın.

sudo apt-get install curl jq

Bazı JSON Verilerini Reddit'ten Alın

Veri akışının nasıl olduğunu görelim. MildlyInteresting alt dizinindeki en son gönderileri almak için curl kullanın:

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

URL: -s önce kullanılan seçeneklerin, Curdit'i sessiz modda çalışmaya zorladığını ve böylece Reddit'in sunucularındaki veriler dışında herhangi bir çıktı göremediğimize dikkat edin. Bir sonraki seçenek ve izleyen parametre, -A “reddit scraper example” , Reddit'in verisine erişen hizmeti tanımlamasına yardımcı olan özel bir kullanıcı aracı dizesini belirler. Reddit API sunucuları, kullanıcı aracısı dizesini temel alarak fiyat limitleri uygular. Özel bir değer belirlemek, Reddit'in ücret limitimizi diğer arayanlardan uzağa bölmesine ve bir HTTP 429 Hız Limiti aşıldı hatası alma şansını azaltmasına neden olur.

Çıktı, terminal penceresini doldurmalı ve şöyle görünmelidir:

Çıktı verilerinde çok fazla alan var, ancak ilgilendiğimiz tek şey Başlık, Kalıcı Bağlantı ve URL. Reddit'in API dokümantasyon sayfasında kapsamlı bir tür listesi ve alanları görebilirsiniz: https://github.com/reddit-archive/reddit/wiki/JSON

JSON Çıktısından Veri Çıkarma

Başlık, Permalink ve URL'yi çıktı verilerinden ayıklamak ve sekmeyle ayrılmış bir dosyaya kaydetmek istiyoruz. sed ve grep gibi metin işleme araçlarını kullanabiliriz, ancak elimizde jq adında JSON veri yapılarını anlayan başka bir aracımız var. İlk denememiz için çıktıyı güzel bir şekilde yazdırmak ve renk kodlamak için kullanalım. Daha önceki ile aynı çağrıyı kullanacağız, ancak bu sefer çıktıyı jq üzerinden yönlendirin ve JSON verilerini ayrıştırıp yazdırmasını isteyin.

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

Komutu takip eden süreye dikkat edin. Bu ifade, girişi basitçe ayrıştırır ve olduğu gibi yazdırır. Çıktı güzel biçimlendirilmiş ve renk kodlu görünüyor:

Reddit’ten geri aldığımız JSON verilerinin yapısını inceleyelim. Kök sonucu iki özellik içeren bir nesnedir: tür ve veri. İkincisi, bu alt dizin için bir dizi posta içeren, children adı verilen bir özelliğe sahiptir.

Dizideki her öğe, tür ve veri olarak da adlandırılan iki alan içeren bir nesnedir. Yakalamak istediğimiz özellikler data nesnesindedir. jq , giriş verilerine uygulanabilecek bir ifade bekler ve istenen çıkışı üretir. İçeriği hiyerarşisi ve bir diziye üyeliği ve ayrıca verinin nasıl dönüştürülmesi gerektiği açısından tanımlamalıdır. Bütün komutu tekrar doğru ifadeyle çalıştıralım:

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

Çıktı, her birinin kendi satırında Başlık, URL ve Permalink’i gösterir:

jq komutuna jq :

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

Bu komutta iki boru sembolüyle ayrılan üç ifade vardır. Her ifadenin sonuçları ileri değerlendirme için bir sonrakine geçirilir. İlk ifade, Reddit listeleri dizisi dışındaki her şeyi filtreler. Bu çıktı ikinci ifadeye aktarılır ve bir diziye zorlanır. Üçüncü ifade, dizideki her öğeye etki eder ve üç özellik çıkarır. jq ve ifade sözdizimi hakkında daha fazla bilgi jq resmi kılavuzunda bulunabilir.

Hepsini bir komut dosyasında bir araya getirmek

Şimdi API çağrısını ve JSON son işlemlerini, istediğimiz yayınlarla bir dosya oluşturacak bir komut dosyasında bir araya getirelim. Yalnızca / r / MildlyInteresting yerine, herhangi bir alt dizinden gönderileri almak için destek ekleyeceğiz.

Editörünüzü açın ve bu pasajın içeriğini scrape-reddit.sh adlı bir dosyaya kopyalayın.

#!/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

Bu komut dosyası önce kullanıcının bir altkredi adı sağlayıp sağlamadığını kontrol eder. Değilse, bir hata mesajı ve sıfır olmayan bir dönüş kodu ile çıkar.

Ardından, ilk argümanı subreddit adı olarak saklar ve çıktının kaydedileceği tarih damgalı bir dosya adı oluşturur.

İşlem, curl özel bir başlıkla çağrıldığında ve sıyrılacak alt dizinin URL'siyle başlatıldığında başlar. Çıktı, ayrıştırıldığı ve üç alana indirildiği jq gönderilir: Başlık, URL ve Permalink. Bu satırlar birer birer okunur ve hepsi bir süre döngüsünün içinde okunacak başka satır bulunmayana kadar devam edecek olan read komutunu kullanarak bir değişkene kaydedilir. İç bölümün son satırı blok, bir sekme karakteri ile sınırlandırılmış üç alanı yankılanır ve ardından çift tırnakların çıkarılabilmesi için tr komutundan geçirir. Çıktı daha sonra bir dosyaya eklenir.

Bu betiği yürütmeden önce, yürütme izinlerinin alındığından emin olmalıyız. Bu izinleri dosyaya uygulamak için chmod komutunu kullanın:

chmod u+x scrape-reddit.sh

Ve son olarak, betiği bir subreddit adıyla yürütün:

./scrape-reddit.sh MildlyInteresting

Bir çıktı dosyası aynı dizinde üretilir ve içeriği şöyle görünür:

Her satır bir sekme karakteri kullanarak ayrıldığımız üç alanı içerir.

Daha İleri Gitmek

Reddit, ilginç içerik ve medyaya sahip bir altın madenidir ve JSON API'sini kullanarak kolayca erişilebilir. Artık bu verilere erişmenin ve sonuçları işlemenin bir yolunu bulduğunuzu söyleyin:

  • / R / WorldNews'den en son haber başlıklarını alın ve notify-send kullanarak masaüstünüze gönderin
  • / R / DadJokes ile gelen en iyi esprileri sisteminizin Günün Mesajına entegre edin
  • / R / aww'den günün en iyi resmini alın ve masaüstü arka planınız yapın

Tüm bunlar, sağlanan verileri ve sisteminizde bulunan araçları kullanarak mümkündür. Mutlu hack!