특히 팟캐스트를 대상으로 특정 RSS 피드에서 파일을 다운로드하도록 설계된 Python 모듈입니다. 어떤 종류의 데이터베이스도 사용하지 않지만 구성 파일이 필요합니다.
스크립트는 주기적으로 실행되도록 만들어졌습니다. 시작하면 이전에 다운로드한 파일을 저장한 디렉터리를 분석합니다. 그런 다음 이러한 파일을 RSS 피드에 나열된 파일과 비교하여 누락된 파일을 식별하고 다운로드합니다.
기본적으로 검색되는 파일은 mp3
입니다.
빈 디렉터리에서 아래 예제를 사용한 결과는 다음과 같습니다.
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 "<none>"
[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 "<none>"
[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
결과:
dplocki@ghost-wheel:~$ tree podcasts/
podcasts/
├── RealPython
│ └── [20240405] rpp_e199_03_calvin.eef1db4d6679.mp3
└── SGTTU
└── skepticast2024-04-06.mp3
2 directories, 2 files
PyPI에서 설치:
pip install podcast_downloader
스크립트가 작동하려면 구성 파일이 필요합니다. 설치 후 스크립트는 Python 모듈로 실행될 수 있습니다.
python -m podcast_downloader
주어진 구성 파일을 사용하여 스크립트를 실행할 수도 있습니다.
python -m podcast_downloader --config my_config.json
구성 파일의 예
{
"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% "
}
]
}
기본적으로 구성 파일은 홈 디렉터리에 저장됩니다. 파일 이름은 .podcast_downloader_config.json
입니다.
구성 파일은 JSON 형식입니다. 예상되는 인코딩은 utf-8입니다.
구성 파일의 경로는 스크립트 인수로 지정할 수 있습니다.
스크립트는 기본값을 구성 파일에서 읽은 값으로 바꿉니다. 명령줄에서 제공된 값으로 인해 과부하가 발생합니다.
command line parameters > configuration file > default values
재산 | 유형 | 필수의? | 기본 | 메모 |
---|---|---|---|---|
downloads_limit | 숫자 | 아니요 | 무한대 | |
if_directory_empty | 끈 | 아니요 | 다운로드_마지막 | 빈 디렉토리의 경우 참조 |
podcast_extensions | 키-값 | 아니요 | {".mp3": "audio/mpeg"} | 파일 형식 필터를 참조하세요. |
podcasts | 일부 | 예 | [] | 팟캐스트 하위 카테고리 보기 |
http_headers | 키-값 | 아니요 | {"User-Agent": "podcast-downloader"} | HTTP 요청 헤더 보기 |
fill_up_gaps | 불리언 | 아니요 | 거짓 | 간격에서 파일 다운로드를 참조하세요. |
download_delay | 숫자 | 아니요 | 0 | 다운로드 지연을 참조하세요. |
podcasts
세그먼트는 다음 콘텐츠가 포함된 객체 배열을 제공하는 구성 파일의 일부입니다.
재산 | 유형 | 필수의 | 기본 | 메모 |
---|---|---|---|---|
name | 끈 | 예 | - | 채널 이름(로거에서 사용) |
rss_link | 끈 | 예 | - | RSS 피드의 URL |
path | 끈 | 예 | - | 팟캐스트가 저장된 디렉토리 경로가 다운로드됩니다. |
file_name_template | 끈 | 아니요 | %file_name%.%file_extension% | 다운로드한 파일의 템플릿은 파일 이름 템플릿을 참조하세요. |
disable | 불리언 | 아니요 | false | 이 팟캐스트는 무시됩니다 |
podcast_extensions | 키-값 | 아니요 | {".mp3": "audio/mpeg"} | 파일 필터 |
if_directory_empty | 끈 | 아니요 | download_last | 빈 디렉토리의 경우 참조 |
require_date | 불리언 | 아니요 | false | 더 이상 사용되지 않습니다. 팟캐스트 날짜를 파일 이름에 추가해야 합니다. file_name_template 을 사용하세요. [%publish_date%] %file_name%.%file_extension%" |
http_headers | 키-값 | 아니요 | {"User-Agent": "podcast-downloader"} | HTTP 요청 헤더 보기 |
fill_up_gaps | 불리언 | 아니요 | 거짓 | 간격에서 파일 다운로드를 참조하세요. |
일부 서버는 urllib가 자신에게 표시되는 방식(HTTP User-Agent 헤더)을 좋아하지 않을 수 있습니다. 이로 인해 다음과 같은 문제가 발생할 수 있습니다: urllib.error.HTTPError: HTTP Error 403: Forbidden
. 그렇기 때문에 파일을 다운로드하는 동안 HTTP 헤더를 지정하여 스크립트가 다른 것으로 위장할 가능성이 있습니다.
구성 파일에서 http_headers
옵션을 사용하십시오. 값은 각 헤더가 키-값 쌍으로 표시되는 사전 개체여야 합니다. 키는 헤더 제목이고 값은 헤더 값입니다.
기본적으로 값은 {"User-Agent": "podcast-downloader"}
입니다. http_headers
에 다른 항목을 제공하면 모든 기본값이 무시됩니다(병합되지 않음).
반면에 팟캐스트 하위 구성에서는 http_headers
가 전역 http_headers
와 병합됩니다. 충돌(동일한 키 이름)이 발생하는 경우 팟캐스트 하위 구성의 값이 전역 값보다 우선 적용됩니다.
예:
{
"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== "
}
}
]
}
이 예에서 Unua 팟캐스트는 헤더가 User-Agent: Mozilla/5.0
이고 Dua 팟캐스트는 User-Agent: podcast-downloader
및 Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
로 다운로드됩니다.
단일 서버에서 다운로드할 파일이 많은 경우 서버에서 공격자로 인식되지 않도록 다운로드 사이에 작은 지연을 설정하는 것이 더 나을 수 있습니다. 스크립트에는 download_delay
라는 옵션이 있는데, 이는 스크립트가 다운로드 사이에 대기하는 시간(초)을 나타냅니다.
기본값은 0
입니다.
참고:
스크립트는 다음 명령줄 인수를 허용합니다.
짧은 버전 | 긴 이름 | 매개변수 | 기본 | 메모 |
---|---|---|---|---|
--config | 끈 | ~/.podcast_downloader_config.json | 구성 파일의 배치 | |
--downloads_limit | 숫자 | 무한대 | 다운로드 가능한 mp3 파일의 최대 개수 | |
--if_directory_empty | 끈 | download_last | 빈 디렉토리에 대한 일반적인 접근 방식 | |
--download_delay | 숫자 | 0 | 다운로드 간 대기 시간(초) |
다운로드 후 파일명을 조정하는데 사용합니다.
기본값( %file_name%.%file_extension%
)은 원본 작성자가 업로드한 대로 파일을 간단하게 저장합니다. 파일 이름과 확장자는 팟캐스트 파일에 대한 링크를 기반으로 합니다.
템플릿 값:
이름 | 메모 |
---|---|
%file_name% | 확장자가 없는 링크의 파일 이름 |
%file_extension% | 링크의 파일 확장자 |
%publish_date% | RSS 항목의 게시 날짜 |
%title% | RSS 항목의 제목 |
%publish_date%
기본적으로 YEARMMDD
형식으로 결과를 제공합니다. 이를 변경하려면 콜론( :
문자) 뒤에 새 항목을 제공할 수 있습니다. 스크립트는 1989 C 표준의 코드를 따르지만 백분율 기호( %
)는 달러 기호( $
)로 바꿔야 합니다. 이는 퍼센트 문자를 코드 표시로 사용하기로 한 불행한 결정 때문입니다.
표준 코드 | 스크립트 코드 | 메모 |
---|---|---|
%Y%m%d | $Y$m$d | %publish_date% 의 기본값 |
%A | $A | 요일 추가 (현지 언어 설정) |
%x | $x | 현지 날짜를 나타냅니다. 경고 : 일부 설정에서는 여기에 / 사용하므로 파일 이름에 문제가 발생할 수 있습니다. |
[%publish_date%] %file_name%.%file_extension%
[%publish_date%] %title%.%file_extension%
팟캐스트는 대부분 *.mp3
파일로 저장됩니다. 기본적으로 Podcast Downloader는 다른 모든 유형을 무시하고 해당 유형만 찾습니다.
팟캐스트가 다른 유형의 미디어 파일을 지원하는 경우 파일 필터를 지정할 수 있습니다. 파일 확장자(예: .mp3
)와 RSS 피드 자체의 링크 유형( mp3
의 경우 audio/mpeg
)을 제공하세요.
파일 형식을 모르는 경우 RSS 파일에서 찾아볼 수 있습니다. enclosure
태그를 찾으면 다음과 같아야 합니다.
< enclosure url = " https://www.vidocast.url/podcast/episode23.m4a "
length = " 14527149 "
type = " audio/x-m4a " />
참고 : 파일 확장자에 점이 필요합니다.
"podcast_extensions" : {
".mp3" : " audio/mpeg " ,
".m4a" : " audio/x-m4a "
}
팟캐스트용 디렉토리가 비어 있으면 스크립트는 무엇을 해야 할지 알아야 합니다. 데이터베이스가 부족하여 다음을 수행할 수 있습니다.
기본 동작은 download_last
입니다.
스크립트는 피드에서 모든 에피소드를 다운로드합니다.
download_all_from_feed
로 설정합니다.
스크립트는 피드에서 마지막 에피소드만 다운로드합니다. 이는 스크립트의 기본 접근 방식이기도 합니다.
download_last
로 설정합니다.
스크립트는 피드에서 지정된 수의 에피소드를 정확하게 다운로드합니다.
download_last_n_episodes
로 설정합니다. n 은 다운로드하려는 에피소드 수로 대체되어야 합니다. 예를 들어, download_last_5_episodes
는 가장 최근 에피소드 5개가 다운로드된다는 의미입니다.
스크립트는 최근 n 일 동안 나타난 모든 에피소드를 다운로드합니다. 정기적으로 다운로드할 때 사용할 수 있습니다. n 숫자는 설정 값( download_from_n_days
내에 제공됩니다. 예를 들어, download_from_3_days
지난 3일 동안의 모든 에피소드를 다운로드한다는 의미입니다.
스크립트는 마지막 에피소드 공개일 이후에 나타나는 모든 에피소드를 다운로드합니다.
n 숫자는 일반 에피소드의 날짜입니다. 여기에 요일을 단어로 입력할 수 있습니다(글자 크기는 무시됩니다).
일주일 내내 | 이름 단축 |
---|---|
월요일 | 월 |
화요일 | 화요일 |
수요일 | 수요일 |
목요일 | 목요일 |
금요일 | 금 |
토요일 | 앉았다 |
일요일 | 해 |
숫자를 제공할 수 있으며, 이는 해당 월의 날짜를 의미합니다. 스크립트는 1부터 28까지의 숫자만 허용합니다.
download_from_
으로 설정합니다.
예:
예시값 | 의미 |
---|---|
download_from_monday | 월요일에 새로운 에피소드가 나옵니다. 스크립트는 지난 화요일 이후의 모든 에피소드(포함)를 다운로드합니다. |
download_from_Fri | 금요일에 새로운 에피소드가 나옵니다. 스크립트는 지난 토요일 이후의 모든 에피소드(포함)를 다운로드합니다. |
download_from_12 | 매월 12일마다 새로운 에피소드가 등장합니다. 스크립트는 13개월 전부터 모든 에피소드를 다운로드합니다. |
토템 파일을 설정하면 스크립트는 이를 사용하여 마지막 실행 날짜를 저장할 수 있습니다. 그런 다음 이 날짜를 기준으로 스크립트는 그 이후에 등장한 모든 새 에피소드를 다운로드합니다.
download_since_last_run
으로 설정합니다. 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 "
}
]
}
스크립트는 파일의 마지막 수정 날짜를 읽고 있습니다. 파일의 수정 날짜는 스크립트에 의해 업데이트됩니다.
스크립트는 다운로드된 파일의 스트림을 인식합니다(피드 데이터를 기반으로). 기본적으로 마지막으로 다운로드한 파일(피드에 따라)이 다운로드 시작을 표시합니다. 공백이 있는 경우, 마지막으로 다운로드한 파일 이전에 누락된 파일이 있는 경우 스크립트는 기본적으로 해당 파일을 무시합니다. 그러나 이미 다운로드한 파일 사이에서 누락된 파일을 모두 다운로드하도록 이 동작을 변경할 가능성이 있습니다. 이를 활성화하려면 fill_up_gaps
값을 true 로 설정해야 합니다. 스크립트는 가장 이전 에피소드인 첫 번째 에피소드(피드에 따라) 이전에는 파일을 다운로드하지 않는다는 점에 유의하는 것이 중요합니다.
기본값: false
.
스크립트는 RSS 파일의 모든 items
노드를 살펴봅니다. item
노드에는 enclosure
노드가 포함될 수 있습니다. 해당 노드는 파일을 전달하는 데 사용됩니다. 규칙에 따르면 단일 item
에는 하나의 enclosure
만 포함되어야 하지만 스크립트(그 아래에 사용되는 라이브러리)는 팟캐스트 item
에 첨부된 여러 파일을 처리할 수 있습니다.
OPML 파일은 구성으로 변환될 수 있습니다. 출력 파일을 조정해야 합니다( path
누락).
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 )
사용 예( opml_converter.py
로 저장한 후):
python opml_converter.py example.opml > podcast_downloader_config.json