Das Python-Modul zum Herunterladen von Dateien aus bestimmten RSS-Feeds, insbesondere für Podcasts. Es verwendet keine Datenbank, sondern erfordert eine Konfigurationsdatei.
Das Skript soll regelmäßig ausgeführt werden. Beim Start analysiert es das Verzeichnis, in dem es zuvor heruntergeladene Dateien gespeichert hat. Anschließend werden diese Dateien mit den im RSS-Feed aufgeführten Dateien verglichen, fehlende Dateien identifiziert und heruntergeladen.
Die standardmäßig durchsuchten Dateien sind mp3
.
Das Ergebnis der Verwendung des folgenden Beispiels für leere Verzeichnisse ist:
dplocki@ghost-wheel:~$ python -m podcast_downloader
[2024-04-08 21:19:10] Loading configuration (from file: "~/.podcast_downloader_config.json")
[2024-04-08 21:19:15] Checking "The Skeptic Guide"
[2024-04-08 21:19:15] Last downloaded file ""
[2024-04-08 21:19:15] The Skeptic Guide: Downloading file: "https://traffic.libsyn.com/secure/skepticsguide/skepticast2024-04-06.mp3" saved as "skepticast2024-04-06.mp3"
[2024-04-08 21:19:41] Checking "The Real Python Podcast"
[2024-04-08 21:19:41] Last downloaded file ""
[2024-04-08 21:19:41] The Real Python Podcast: Downloading file: "https://chtbl.com/track/92DB94/files.realpython.com/podcasts/RPP_E199_03_Calvin.eef1db4d6679.mp3" saved as "[20240405] rpp_e199_03_calvin.eef1db4d6679.mp3"
[2024-04-08 21:20:04] Finished
Das Ergebnis:
dplocki@ghost-wheel:~$ tree podcasts/
podcasts/
├── RealPython
│ └── [20240405] rpp_e199_03_calvin.eef1db4d6679.mp3
└── SGTTU
└── skepticast2024-04-06.mp3
2 directories, 2 files
Installation von PyPI:
pip install podcast_downloader
Damit das Skript funktioniert, ist eine Konfigurationsdatei erforderlich. Nach der Installation kann das Skript als beliebiges Python-Modul ausgeführt werden:
python -m podcast_downloader
Es ist auch möglich, das Skript mit der angegebenen Konfigurationsdatei auszuführen:
python -m podcast_downloader --config my_config.json
Ein Beispiel für eine Konfigurationsdatei
{
"if_directory_empty" : " download_from_4_days " ,
"podcasts" : [
{
"name" : " The Skeptic Guide " ,
"rss_link" : " https://feed.theskepticsguide.org/feed/rss.aspx " ,
"path" : " ~/podcasts/SGTTU "
},
{
"rss_link" : " https://realpython.com/podcasts/rpp/feed " ,
"path" : " ~/podcasts/RealPython " ,
"file_name_template" : " [%publish_date%] %file_name%.%file_extension% "
}
]
}
Standardmäßig wird die Konfigurationsdatei im Home-Verzeichnis abgelegt. Der Dateiname lautet: .podcast_downloader_config.json
.
Die Konfigurationsdatei ist im JSON-Format formatiert. Die erwartete Kodierung ist utf-8.
Der Pfad zur Konfigurationsdatei kann durch ein Skriptargument angegeben werden.
Das Skript ersetzt Standardwerte durch diejenigen, die aus der Konfigurationsdatei gelesen werden. Diese werden durch Werte überlastet, die über die Befehlszeile eingegeben werden.
command line parameters > configuration file > default values
Eigentum | Typ | Erforderlich? | Standard | Notiz |
---|---|---|---|---|
downloads_limit | Nummer | NEIN | Unendlichkeit | |
if_directory_empty | Zeichenfolge | NEIN | download_last | Siehe Bei leerem Verzeichnis |
podcast_extensions | Schlüsselwert | NEIN | {".mp3": "audio/mpeg"} | Siehe Dateitypfilter |
podcasts | Unterabschnitt | Ja | [] | Siehe Unterkategorie „Podcasts“. |
http_headers | Schlüsselwert | NEIN | {"User-Agent": "podcast-downloader"} | Siehe HTTP-Anfrageheader |
fill_up_gaps | Boolescher Wert | NEIN | FALSCH | Siehe Dateien aus Lücken herunterladen |
download_delay | Nummer | NEIN | 0 | Siehe Download-Verzögerung |
Das podcasts
Segment ist der Teil der Konfigurationsdatei, in dem Sie das Array von Objekten mit folgendem Inhalt bereitstellen:
Eigentum | Typ | Erforderlich | Standard | Notiz |
---|---|---|---|---|
name | Zeichenfolge | Ja | - | Der Name des Kanals (Verwendung im Logger) |
rss_link | Zeichenfolge | Ja | - | Die URL des RSS-Feeds |
path | Zeichenfolge | Ja | - | Der Pfad zum Verzeichnis, in dem Podcasts gespeichert sind, wird heruntergeladen |
file_name_template | Zeichenfolge | NEIN | %file_name%.%file_extension% | Die Vorlage für die heruntergeladenen Dateien finden Sie unter Dateinamenvorlage |
disable | Boolescher Wert | NEIN | false | Dieser Podcast wird ignoriert |
podcast_extensions | Schlüsselwert | NEIN | {".mp3": "audio/mpeg"} | Der Dateifilter |
if_directory_empty | Zeichenfolge | NEIN | download_last | Siehe Bei leerem Verzeichnis |
require_date | Boolescher Wert | NEIN | false | Veraltet: Das Datum des Podcasts sollte zum Dateinamen hinzugefügt werden – verwenden Sie die file_name_template “: [%publish_date%] %file_name%.%file_extension%" |
http_headers | Schlüsselwert | NEIN | {"User-Agent": "podcast-downloader"} | Siehe HTTP-Anfrageheader |
fill_up_gaps | Boolescher Wert | NEIN | FALSCH | Siehe Dateien aus Lücken herunterladen |
Einigen Servern gefällt möglicherweise nicht, wie sich ihnen die URLib präsentiert (der HTTP-User-Agent-Header). Dies kann zu Problemen führen wie: urllib.error.HTTPError: HTTP Error 403: Forbidden
. Aus diesem Grund besteht die Möglichkeit, dass sich das Skript als etwas anderes ausgibt: indem es beim Herunterladen von Dateien die HTTP-Header angibt.
Verwenden Sie die Option http_headers
in der Konfigurationsdatei. Der Wert sollte ein Wörterbuchobjekt sein, bei dem jeder Header als Schlüssel-Wert-Paar dargestellt wird. Der Schlüssel ist der Header-Titel und der Wert ist der Header-Wert.
Standardmäßig ist der Wert: {"User-Agent": "podcast-downloader"}
. Wenn Sie etwas anderes für http_headers
angeben, werden alle Standardwerte überschrieben (sie werden nicht zusammengeführt).
Andererseits werden in der Podcast-Unterkonfiguration die http_headers
mit den globalen http_headers
zusammengeführt. Im Falle eines Konflikts (gleicher Schlüsselname) überschreibt der Wert aus der Podcast-Unterkonfiguration den globalen Wert.
Beispiel:
{
"http_headers" : {
"User-Agent" : " podcast-downloader "
},
"podcasts" : [
{
"name" : " Unua Podcast " ,
"rss_link" : " http://www.unuapodcast.org/feed.rss " ,
"path" : " ~/podcasts/unua_podcast " ,
"https_headers" : {
"User-Agent" : " Mozilla/5.0 "
}
},
{
"name" : " Dua Podcast " ,
"rss_link" : " http://www.duapodcast.org/feed.rss " ,
"path" : " ~/podcasts/dua_podcast " ,
"https_headers" : {
"Authorization" : " Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== "
}
}
]
}
In diesem Beispiel wird der Unua-Podcast nur mit dem Header „ User-Agent: Mozilla/5.0
“ und der Dua-Podcast mit „ User-Agent: podcast-downloader
und Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
heruntergeladen.
Wenn Sie viele Dateien von einem einzigen Server herunterladen müssen, ist es möglicherweise besser, eine kurze Verzögerung zwischen den Downloads einzurichten, um zu vermeiden, dass der Server sie als Angreifer erkennt. Im Skript gibt es eine Option namens download_delay
, die die Anzahl der Sekunden angibt, die das Skript zwischen den Downloads wartet.
Der Standardwert ist 0
.
Hinweise:
Das Skript akzeptiert folgende Befehlszeilenargumente:
Kurzfassung | Langer Name | Parameter | Standard | Notiz |
---|---|---|---|---|
--config | Zeichenfolge | ~/.podcast_downloader_config.json | Die Platzierung der Konfigurationsdatei | |
--downloads_limit | Nummer | Unendlichkeit | Die maximale Anzahl heruntergeladener MP3-Dateien | |
--if_directory_empty | Zeichenfolge | download_last | Der allgemeine Ansatz für leere Verzeichnisse | |
--download_delay | Nummer | 0 | Die Wartezeit (Sekunden) zwischen Downloads |
Verwenden Sie diese Option, um den Dateinamen nach dem Herunterladen anzupassen.
Der Standardwert ( %file_name%.%file_extension%
) speichert die Datei einfach so, wie sie vom ursprünglichen Ersteller hochgeladen wurde. Der Dateiname und seine Erweiterung basieren auf dem Link zur Podcast-Datei.
Vorlagenwerte:
Name | Notizen |
---|---|
%file_name% | Der Dateiname aus dem Link, ohne Erweiterung |
%file_extension% | Die Erweiterung für die Datei, vom Link |
%publish_date% | Das Veröffentlichungsdatum des RSS-Eintrags |
%title% | Der Titel des RSS-Eintrags |
Das %publish_date%
gibt standardmäßig ein Ergebnis im Format YEARMMDD
aus. Um es zu ändern, können Sie das neue nach dem Doppelpunkt (das :
-Zeichen) angeben. Das Skript respektiert die Codes des C-Standards von 1989, das Prozentzeichen ( %
) muss jedoch durch ein Dollarzeichen ( $
) ersetzt werden. Das liegt an meiner unglücklichen Entscheidung, das Prozentzeichen als Markierung des Codes zu verwenden.
Der Standardcode | Der Skriptcode | Notizen |
---|---|---|
%Y%m%d | $Y$m$d | Der Standardwert von %publish_date% |
%A | $A | Fügt den Wochentag hinzu (lokale Spracheinstellungen) |
%x | $x | Das lokale Datum darstellen. Warnung : In einigen Einstellungen wird hier das / verwendet, daher kann es zu Problemen mit dem Dateinamen kommen |
[%publish_date%] %file_name%.%file_extension%
[%publish_date%] %title%.%file_extension%
Podcasts werden meist als *.mp3
Dateien gespeichert. Standardmäßig sucht Podcast Downloader nur nach ihnen und ignoriert alle anderen Typen.
Wenn Ihr Podcast andere Arten von Mediendateien unterstützt, können Sie die Dateifilter festlegen. Geben Sie die Erweiterung der Datei (z. B. .mp3
) und den Linktyp im RSS-Feed selbst an (für mp3
ist es audio/mpeg
).
Wenn Sie den Dateityp nicht kennen, können Sie in der RSS-Datei danach suchen. Suchen Sie nach enclosure
-Tags. Das sollte so aussehen:
< enclosure url = " https://www.vidocast.url/podcast/episode23.m4a " length = " 14527149 " type = " audio/x-m4a " />
Hinweis : Der Punkt in der Dateierweiterung ist erforderlich.
"podcast_extensions" : {
".mp3" : " audio/mpeg " ,
".m4a" : " audio/x-m4a "
}
Wenn ein Verzeichnis für Podcasts leer ist, muss das Skript wissen, was zu tun ist. Aufgrund fehlender Datenbank können Sie:
Das Standardverhalten ist: download_last
Das Skript lädt alle Episoden aus dem Feed herunter.
Wird von download_all_from_feed
festgelegt.
Das Skript lädt nur die letzte Episode aus dem Feed herunter. Dies ist auch der Standardansatz des Skripts.
Wird von download_last
festgelegt.
Das Skript lädt genau die angegebene Anzahl an Episoden aus dem Feed herunter.
Festgelegt durch download_last_n_episodes
. Das n muss durch die Anzahl der Episoden ersetzt werden, die Sie heruntergeladen haben wollten. Beispiel: download_last_5_episodes
bedeutet, dass fünf aktuelle Episoden heruntergeladen werden.
Das Skript lädt alle Episoden herunter, die in den letzten n Tagen erschienen sind. Es kann verwendet werden, wenn Sie regelmäßig herunterladen. Die n -Nummer wird im Setup-Wert angegeben: download_from_n_days
. Beispiel: download_from_3_days
bedeutet, dass alle Episoden der letzten 3 Tage heruntergeladen werden.
Das Skript lädt alle Episoden herunter, die nach dem Veröffentlichungstag der letzten Episode erscheinen.
Die Zahl n ist der Tag der normalen Episode. Sie können hier Wochentage als Wort angeben (Größe der Buchstaben wird ignoriert)
Ganzer Wochentag | Namen kürzen |
---|---|
Montag | Mo |
Dienstag | Dienstag |
Mittwoch | Mi |
Donnerstag | Do |
Freitag | Fr |
Samstag | Sa |
Sonntag | Sonne |
Sie können die Nummer angeben, sie bedeutet den Tag des Monats. Das Skript akzeptiert nur Zahlen von 1 bis 28.
Wird von download_from_
festgelegt.
Beispiele:
Beispielwert | Bedeutung |
---|---|
download_from_monday | Neue Folgen erscheinen am Montag. Das Drehbuch lädt alle Episoden seit letztem Dienstag herunter (einschließlich dieser). |
download_from_Fri | Neue Folgen erscheinen am Freitag. Das Drehbuch lädt alle Episoden seit letztem Samstag herunter (einschließlich dieser). |
download_from_12 | Jeden 12. Monat erscheinen neue Folgen. Das Drehbuch lädt alle Episoden seit 13 Monaten herunter |
Sobald Sie die Totemdatei erstellt haben, kann das Skript damit das Datum seiner letzten Ausführung speichern. Basierend auf diesem Datum lädt das Skript dann alle neuen Episoden herunter, die seitdem erschienen sind.
Wird durch download_since_last_run
festgelegt. Erfordert die Erstellung der Speicherdatei durch last_run_mark_file_path
.
{
"last_run_mark_file_path" : " ~/.totem.json " ,
"podcasts" : [
{
"name" : " The Skeptic Guide " ,
"rss_link" : " https://feed.theskepticsguide.org/feed/rss.aspx " ,
"path" : " ~/podcasts/SGTTU "
}
]
}
Das Skript liest das Datum der letzten Änderung der Datei. Das Änderungsdatum der Datei wird vom Skript aktualisiert.
Das Skript erkennt den Stream heruntergeladener Dateien (basierend auf den Feed-Daten). Standardmäßig markiert die zuletzt heruntergeladene Datei (laut Feed) den Beginn des Downloads. Im Falle von Lücken, also Situationen, in denen vor der zuletzt heruntergeladenen Datei fehlende Dateien vorhanden sind, ignoriert das Skript diese standardmäßig. Es besteht jedoch die Möglichkeit, dieses Verhalten zu ändern, um alle fehlenden Dateien zwischen bereits heruntergeladenen Dateien herunterzuladen. Um dies zu aktivieren, müssen Sie den Wert fill_up_gaps
auf true setzen. Es ist wichtig zu beachten, dass das Skript keine Dateien vor der ersten (laut Feed) herunterlädt, also der frühesten Episode.
Standardwert: false
.
Das Skript durchsucht alle items
in der RSS-Datei. Der item
kann den enclosure
enthalten. Diese Knoten werden zur Weitergabe der Dateien verwendet. Gemäß der Konvention sollte das einzelne item
nur ein enclosure
enthalten, aber das Skript (als die darunter verwendete Bibliothek) kann die mehreren an das Podcast- item
angehängten Dateien verarbeiten.
Die OPML-Dateien können in Konfigurationen umgewandelt werden. Die Ausgabedatei muss angepasst werden (der path
fehlt).
import json
import sys
import xml . etree . ElementTree as ET
def build_podcast ( node_rss ):
return {
"name" : node_rss . attrib [ "title" ],
"rss_link" : node_rss . attrib [ "xmlUrl" ],
"path" : "" ,
}
tree = ET . parse ( sys . argv [ 1 ])
podcasts = list ( map ( build_podcast , tree . findall ( "body/outline[@type='rss']" )))
result = json . dumps ({ "podcasts" : podcasts }, sort_keys = True , indent = 4 )
print ( result )
Anwendungsbeispiel (nach dem Speichern als opml_converter.py
):
python opml_converter.py example.opml > podcast_downloader_config.json