dlf.py 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. import re
  2. from .common import InfoExtractor
  3. from ..utils import (
  4. determine_ext,
  5. extract_attributes,
  6. int_or_none,
  7. traverse_obj,
  8. url_or_none,
  9. )
  10. class DLFBaseIE(InfoExtractor):
  11. _VALID_URL_BASE = r'https?://(?:www\.)?deutschlandfunk\.de/'
  12. _BUTTON_REGEX = r'(<button[^>]+alt="Anhören"[^>]+data-audio-diraid[^>]*>)'
  13. def _parse_button_attrs(self, button, audio_id=None):
  14. attrs = extract_attributes(button)
  15. audio_id = audio_id or attrs['data-audio-diraid']
  16. url = traverse_obj(
  17. attrs, 'data-audio-download-src', 'data-audio', 'data-audioreference',
  18. 'data-audio-src', expected_type=url_or_none)
  19. ext = determine_ext(url)
  20. return {
  21. 'id': audio_id,
  22. 'extractor_key': DLFIE.ie_key(),
  23. 'extractor': DLFIE.IE_NAME,
  24. **traverse_obj(attrs, {
  25. 'title': (('data-audiotitle', 'data-audio-title', 'data-audio-download-tracking-title'), {str}),
  26. 'duration': (('data-audioduration', 'data-audio-duration'), {int_or_none}),
  27. 'thumbnail': ('data-audioimage', {url_or_none}),
  28. 'uploader': 'data-audio-producer',
  29. 'series': 'data-audio-series',
  30. 'channel': 'data-audio-origin-site-name',
  31. 'webpage_url': ('data-audio-download-tracking-path', {url_or_none}),
  32. }, get_all=False),
  33. 'formats': (self._extract_m3u8_formats(url, audio_id, fatal=False)
  34. if ext == 'm3u8' else [{'url': url, 'ext': ext, 'vcodec': 'none'}]),
  35. }
  36. class DLFIE(DLFBaseIE):
  37. IE_NAME = 'dlf'
  38. _VALID_URL = DLFBaseIE._VALID_URL_BASE + r'[\w-]+-dlf-(?P<id>[\da-f]{8})-100\.html'
  39. _TESTS = [
  40. # Audio as an HLS stream
  41. {
  42. 'url': 'https://www.deutschlandfunk.de/tanz-der-saiteninstrumente-das-wild-strings-trio-aus-slowenien-dlf-03a3eb19-100.html',
  43. 'info_dict': {
  44. 'id': '03a3eb19',
  45. 'title': r're:Tanz der Saiteninstrumente [-/] Das Wild Strings Trio aus Slowenien',
  46. 'ext': 'm4a',
  47. 'duration': 3298,
  48. 'thumbnail': 'https://assets.deutschlandfunk.de/FALLBACK-IMAGE-AUDIO/512x512.png?t=1603714364673',
  49. 'uploader': 'Deutschlandfunk',
  50. 'series': 'On Stage',
  51. 'channel': 'deutschlandfunk',
  52. },
  53. 'params': {
  54. 'skip_download': 'm3u8',
  55. },
  56. 'skip': 'This webpage no longer exists',
  57. }, {
  58. 'url': 'https://www.deutschlandfunk.de/russische-athleten-kehren-zurueck-auf-die-sportbuehne-ein-gefaehrlicher-tueroeffner-dlf-d9cc1856-100.html',
  59. 'info_dict': {
  60. 'id': 'd9cc1856',
  61. 'title': 'Russische Athleten kehren zurück auf die Sportbühne: Ein gefährlicher Türöffner',
  62. 'ext': 'mp3',
  63. 'duration': 291,
  64. 'thumbnail': 'https://assets.deutschlandfunk.de/FALLBACK-IMAGE-AUDIO/512x512.png?t=1603714364673',
  65. 'uploader': 'Deutschlandfunk',
  66. 'series': 'Kommentare und Themen der Woche',
  67. 'channel': 'deutschlandfunk',
  68. },
  69. },
  70. ]
  71. def _real_extract(self, url):
  72. audio_id = self._match_id(url)
  73. webpage = self._download_webpage(url, audio_id)
  74. return self._parse_button_attrs(
  75. self._search_regex(self._BUTTON_REGEX, webpage, 'button'), audio_id)
  76. class DLFCorpusIE(DLFBaseIE):
  77. IE_NAME = 'dlf:corpus'
  78. IE_DESC = 'DLF Multi-feed Archives'
  79. _VALID_URL = DLFBaseIE._VALID_URL_BASE + r'(?P<id>(?![\w-]+-dlf-[\da-f]{8})[\w-]+-\d+)\.html'
  80. _TESTS = [
  81. # Recorded news broadcast with referrals to related broadcasts
  82. {
  83. 'url': 'https://www.deutschlandfunk.de/fechten-russland-belarus-ukraine-protest-100.html',
  84. 'info_dict': {
  85. 'id': 'fechten-russland-belarus-ukraine-protest-100',
  86. 'title': r're:Wiederzulassung als neutrale Athleten [-/] Was die Rückkehr russischer und belarussischer Sportler beim Fechten bedeutet',
  87. 'description': 'md5:91340aab29c71aa7518ad5be13d1e8ad',
  88. },
  89. 'playlist_mincount': 5,
  90. 'playlist': [{
  91. 'info_dict': {
  92. 'id': '1fc5d64a',
  93. 'title': r're:Wiederzulassung als neutrale Athleten [-/] Was die Rückkehr russischer und belarussischer Sportler beim Fechten bedeutet',
  94. 'ext': 'mp3',
  95. 'duration': 252,
  96. 'thumbnail': 'https://assets.deutschlandfunk.de/aad16241-6b76-4a09-958b-96d0ee1d6f57/512x512.jpg?t=1679480020313',
  97. 'uploader': 'Deutschlandfunk',
  98. 'series': 'Sport',
  99. 'channel': 'deutschlandfunk',
  100. },
  101. }, {
  102. 'info_dict': {
  103. 'id': '2ada145f',
  104. 'title': r're:(?:Sportpolitik / )?Fechtverband votiert für Rückkehr russischer Athleten',
  105. 'ext': 'mp3',
  106. 'duration': 336,
  107. 'thumbnail': 'https://assets.deutschlandfunk.de/FILE_93982766f7317df30409b8a184ac044a/512x512.jpg?t=1678547581005',
  108. 'uploader': 'Deutschlandfunk',
  109. 'series': 'Deutschlandfunk Nova',
  110. 'channel': 'deutschlandfunk-nova',
  111. },
  112. }, {
  113. 'info_dict': {
  114. 'id': '5e55e8c9',
  115. 'title': r're:Wiederzulassung von Russland und Belarus [-/] "Herumlavieren" des Fechter-Bundes sorgt für Unverständnis',
  116. 'ext': 'mp3',
  117. 'duration': 187,
  118. 'thumbnail': 'https://assets.deutschlandfunk.de/a595989d-1ed1-4a2e-8370-b64d7f11d757/512x512.jpg?t=1679173825412',
  119. 'uploader': 'Deutschlandfunk',
  120. 'series': 'Sport am Samstag',
  121. 'channel': 'deutschlandfunk',
  122. },
  123. }, {
  124. 'info_dict': {
  125. 'id': '47e1a096',
  126. 'title': r're:Rückkehr Russlands im Fechten [-/] "Fassungslos, dass es einfach so passiert ist"',
  127. 'ext': 'mp3',
  128. 'duration': 602,
  129. 'thumbnail': 'https://assets.deutschlandfunk.de/da4c494a-21cc-48b4-9cc7-40e09fd442c2/512x512.jpg?t=1678562155770',
  130. 'uploader': 'Deutschlandfunk',
  131. 'series': 'Sport am Samstag',
  132. 'channel': 'deutschlandfunk',
  133. },
  134. }, {
  135. 'info_dict': {
  136. 'id': '5e55e8c9',
  137. 'title': r're:Wiederzulassung von Russland und Belarus [-/] "Herumlavieren" des Fechter-Bundes sorgt für Unverständnis',
  138. 'ext': 'mp3',
  139. 'duration': 187,
  140. 'thumbnail': 'https://assets.deutschlandfunk.de/a595989d-1ed1-4a2e-8370-b64d7f11d757/512x512.jpg?t=1679173825412',
  141. 'uploader': 'Deutschlandfunk',
  142. 'series': 'Sport am Samstag',
  143. 'channel': 'deutschlandfunk',
  144. },
  145. }],
  146. },
  147. # Podcast feed with tag buttons, playlist count fluctuates
  148. {
  149. 'url': 'https://www.deutschlandfunk.de/kommentare-und-themen-der-woche-100.html',
  150. 'info_dict': {
  151. 'id': 'kommentare-und-themen-der-woche-100',
  152. 'title': 'Meinung - Kommentare und Themen der Woche',
  153. 'description': 'md5:2901bbd65cd2d45e116d399a099ce5d5',
  154. },
  155. 'playlist_mincount': 10,
  156. },
  157. # Podcast feed with no description
  158. {
  159. 'url': 'https://www.deutschlandfunk.de/podcast-tolle-idee-100.html',
  160. 'info_dict': {
  161. 'id': 'podcast-tolle-idee-100',
  162. 'title': 'Wissenschaftspodcast - Tolle Idee! - Was wurde daraus?',
  163. },
  164. 'playlist_mincount': 11,
  165. },
  166. ]
  167. def _real_extract(self, url):
  168. playlist_id = self._match_id(url)
  169. webpage = self._download_webpage(url, playlist_id)
  170. return {
  171. '_type': 'playlist',
  172. 'id': playlist_id,
  173. 'description': self._html_search_meta(
  174. ['description', 'og:description', 'twitter:description'], webpage, default=None),
  175. 'title': self._html_search_meta(
  176. ['og:title', 'twitter:title'], webpage, default=None),
  177. 'entries': map(self._parse_button_attrs, re.findall(self._BUTTON_REGEX, webpage)),
  178. }