{"record":{"id":"81b49c799fdb98e7","repo":"ytdl-org/youtube-dl","slug":"no-episodes-found","errorCode":null,"errorMessage":"No episodes found","messagePattern":"No episodes found","errorType":"exception","errorClass":"ExtractorError","httpStatus":null,"severity":"error","filePath":"youtube_dl/extractor/youku.py","lineNumber":264,"sourceCode":"        'url': 'http://list.youku.com/show/id_zefbfbd61237fefbfbdef.html',\n        'only_matching': True,\n    }, {\n        #  Wrong number of reload_id.\n        'url': 'http://list.youku.com/show/id_z20eb4acaf5c211e3b2ad.html',\n        'only_matching': True,\n    }]\n\n    def _extract_entries(self, playlist_data_url, show_id, note, query):\n        query['callback'] = 'cb'\n        playlist_data = self._download_json(\n            playlist_data_url, show_id, query=query, note=note,\n            transform_source=lambda s: js_to_json(strip_jsonp(s))).get('html')\n        if playlist_data is None:\n            return [None, None]\n        drama_list = (get_element_by_class('p-drama-grid', playlist_data)\n                      or get_element_by_class('p-drama-half-row', playlist_data))\n        if drama_list is None:\n            raise ExtractorError('No episodes found')\n        video_urls = re.findall(r'<a[^>]+href=\"([^\"]+)\"', drama_list)\n        return playlist_data, [\n            self.url_result(self._proto_relative_url(video_url, 'http:'), YoukuIE.ie_key())\n            for video_url in video_urls]\n\n    def _real_extract(self, url):\n        show_id = self._match_id(url)\n        webpage = self._download_webpage(url, show_id)\n\n        entries = []\n        page_config = self._parse_json(self._search_regex(\n            r'var\\s+PageConfig\\s*=\\s*({.+});', webpage, 'page config'),\n            show_id, transform_source=js_to_json)\n        first_page, initial_entries = self._extract_entries(\n            'http://list.youku.com/show/module', show_id,\n            note='Downloading initial playlist data page',\n            query={\n                'id': page_config['showid'],","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/youku.py#L246-L282","documentation":"Raised by YoukuShowIE._extract_entries when the playlist/show HTML returned by the show API does not contain the expected drama-list markup. The code looks for an element with class 'p-drama-grid' or 'p-drama-half-row' via get_element_by_class; if neither is present in playlist_data, it concludes there are no episodes and raises. This means the show page either truly has no listed episodes or Youku changed its playlist HTML structure.","triggerScenarios":"Extracting a Youku show URL (show.youku.com) where the returned html field lacks both 'p-drama-grid' and 'p-drama-half-row' containers — empty/removed shows, region-served fallback pages, or a template change by Youku.","commonSituations":"Shows taken down or not yet published in the requested region; Youku shipping a new CSS class scheme for episode grids; the JSONP payload (parsed via js_to_json(strip_jsonp(...))) containing an error/placeholder page instead of the drama grid.","solutions":["Open the show URL in a browser and confirm episodes are actually listed for your region; if none, the error is correct.","Dump the playlist_data HTML (print or log it before the check) and inspect what container class the episodes now use.","Add the new class name to the get_element_by_class fallback chain in _extract_entries, e.g. get_element_by_class('p-drama-<new-class>', playlist_data).","Verify the JSONP transform still yields valid JSON — if .get('html') returns an error page, fix the query params (callback='cb') or endpoint first."],"exampleFix":"// before\ndrama_list = (get_element_by_class('p-drama-grid', playlist_data)\n              or get_element_by_class('p-drama-half-row', playlist_data))\n\n// after\ndrama_list = (get_element_by_class('p-drama-grid', playlist_data)\n              or get_element_by_class('p-drama-half-row', playlist_data)\n              or get_element_by_class('p-drama-new-grid', playlist_data))  // class observed in current HTML","handlingStrategy":"validation","validationCode":"def has_episode_grid(playlist_html: str) -> bool:\n    return ('p-drama-grid' in playlist_html\n            or 'p-drama-half-row' in playlist_html)","typeGuard":null,"tryCatchPattern":"try:\n    entries = ydl.extract_info(show_url)\nexcept ExtractorError as e:\n    if 'No episodes found' in str(e):\n        # verify manually: page may genuinely be empty or markup changed\n        log_and_flag_for_review(show_url)\n    else:\n        raise","preventionTips":["Before bulk-crawling shows, spot-check one show page's HTML for the drama-grid class.","Track upstream extractor commits when Youku redesigns pages; HTML-scraping breakage is routine."],"tags":["youku","playlist","html-scraping","site-change"],"backgroundTag":null,"analyzedSha":"956b8c585591b401a543e409accb163eeaaa1193","analyzedAt":"2026-08-14T18:59:47.863Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}