{"record":{"id":"d104bfb4e81515c8","repo":"soimort/you-get","slug":"no-video-found-in-this-playlist","errorCode":null,"errorMessage":"No video found in this playlist","messagePattern":"No video found in this playlist","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/you_get/extractors/icourses.py","lineNumber":166,"sourceCode":"            page = to_chap(hit.group(1), hit.group(2), hit.group(3))\n            hit_list = re.findall(res_patt, page)\n            if hit_list:\n                return get_playlist(hit_list[0][0], hit_list[0][1])\n            for hit in hit_list:\n                print(hit)\n        elif i[1] == 'showSectionNode2':\n            hit = re.search(show_sec_patt, i[2])\n            page = show_sec(hit.group(1), hit.group(2))\n            # print(page)\n            patt = r'ajaxtosection\\(this,(\\d+),(\\d+),(\\d+)\\)'\n            hit_list = re.findall(patt, page)\n            # print(hit_list)\n            for hit in hit_list:\n                page = to_sec(hit[0], hit[1], hit[2])\n                vlist = re.findall(res_patt, page)\n                if vlist:\n                    return get_playlist(vlist[0][0], vlist[0][1])\n    raise Exception(\"No video found in this playlist\")\n\n\ndef get_playlist(res_id, course_id):\n    ep = 'http://www.icourses.cn/jpk/changeforVideo.action?resId={}&courseId={}'\n    req = get_content(ep.format(res_id, course_id))\n\n    patt = r'<a.+?changeforvideo\\(\\'(\\d+)\\',\\'(\\d+)\\',\\'(\\d+)\\'\\).+?title=\\\"(.+?)\\\"'\n    return re.findall(patt, req)\n\n\nclass ICousesExactor(object):\n    PLAYER_BASE_VER = '150606-1'\n    ENCRYPT_MOD_VER = '151020'\n    ENCRYPT_SALT = '3DAPmXsZ4o'  # It took really long time to find this...\n\n    def __init__(self, url):\n        self.url = url\n        self.title = ''","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/soimort/you-get/blob/049548f3f3f35e67ba8d3181c71fdc71d11cf260/src/you_get/extractors/icourses.py#L148-L184","documentation":"Raised as plain Exception at the end of icourses_playlist_new (src/you_get/extractors/icourses.py:166). This function walks the course's chapter/section tree (showSectionNode2 -> to_sec -> get_playlist) looking for videos; if no branch ever yields a non-empty vlist, the playlist is considered video-less.","triggerScenarios":"icourses_playlist_download hits the type-2 shared-course branch and icourses_playlist_new traverses all ajaxtosection(...) nodes, but every to_sec(...) page has no matches for res_patt; or the intermediate regexes (show_sec_patt etc.) fail so no section is even visited. The unconditional raise at function bottom then fires.","commonSituations":"Course that genuinely contains no downloadable videos (documents only); icourses markup/JS changes (ajaxtosection signature changed) so section pages parse empty; missing/garbled course data served to the scraper.","solutions":["Open the course in a browser and confirm it actually has videos.","Log each section page fetched in icourses_playlist_new and check whether res_patt (and the ajaxtosection/show_sec_patt regexes) still match the HTML; update them if the markup changed.","Upgrade you-get for current icourses page structure."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    icourses_playlist_download(url, output_dir)\nexcept Exception as e:\n    if str(e) == 'No video found in this playlist':\n        verify_course_has_videos_in_browser(url)  # content question, not code\n    else:\n        raise","preventionTips":["Confirm the course actually contains videos before automating.","Log section pages during traversal so empty results can be distinguished from regex rot."],"tags":["you-get","icourses","playlist","no-content","extractor"],"backgroundTag":null,"analyzedSha":"049548f3f3f35e67ba8d3181c71fdc71d11cf260","analyzedAt":"2026-08-15T03:58:15.069Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}