{"record":{"id":"ab5af8eb3ed8a97a","repo":"NanmiCoder/MediaCrawler","slug":"playwright-page-is-required-for-browser-based-sub","errorCode":null,"errorMessage":"playwright_page is required for browser-based sub-comment fetching","messagePattern":"playwright_page is required for browser-based sub-comment fetching","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"media_platform/tieba/client.py","lineNumber":537,"sourceCode":"        crawl_interval: float = 1.0,\n        callback: Optional[Callable] = None,\n    ) -> List[TiebaComment]:\n        \"\"\"\n        Get all sub-comments for specified comments (uses Playwright to access page, avoiding API detection)\n        Args:\n            comments: Comment list\n            crawl_interval: Crawl delay interval in seconds\n            callback: Callback function after one post crawl completes\n\n        Returns:\n            List[TiebaComment]: Sub-comment list\n        \"\"\"\n        if not config.ENABLE_GET_SUB_COMMENTS:\n            return []\n\n        if not self.playwright_page:\n            utils.logger.error(\"[BaiduTieBaClient.get_comments_all_sub_comments] playwright_page is None, cannot use browser mode\")\n            raise Exception(\"playwright_page is required for browser-based sub-comment fetching\")\n\n        all_sub_comments: List[TiebaComment] = []\n\n        for parment_comment in comments:\n            if parment_comment.sub_comment_count == 0:\n                continue\n\n            current_page = 1\n            max_sub_page_num = parment_comment.sub_comment_count // 10 + 1\n\n            while max_sub_page_num >= current_page:\n                # Construct sub-comment URL\n                sub_comment_url = (\n                    f\"{self._host}/p/comment?\"\n                    f\"tid={parment_comment.note_id}&\"\n                    f\"pid={parment_comment.comment_id}&\"\n                    f\"fid={parment_comment.tieba_id}&\"\n                    f\"pn={current_page}\"","sourceCodeStart":519,"sourceCodeEnd":555,"githubUrl":"https://github.com/NanmiCoder/MediaCrawler/blob/d6f7c5bb906b6dac40ddf343ef9e26438a3de092/media_platform/tieba/client.py#L519-L555","documentation":"Raised by BaiduTieBaClient.get_comments_all_sub_comments (media_platform/tieba/client.py:537) when sub-comment crawling is enabled (config.ENABLE_GET_SUB_COMMENTS true) but self.playwright_page is None. Note the early return above: with the flag off the method returns [] silently; with it on and no browser page it raises. Sub-comment pages are fetched by browser navigation, hence the requirement.","triggerScenarios":"ENABLE_GET_SUB_COMMENTS=true combined with a client lacking playwright_page; any call to get_comments_all_sub_comments(comments, ...) under those conditions raises before iterating comments.","commonSituations":"Turning on sub-comment crawling in a pipeline that previously ran browserless; browser closed between note crawl and sub-comment crawl; tests enabling the flag without providing a page mock.","solutions":["Attach a Playwright page to the client when ENABLE_GET_SUB_COMMENTS is enabled","Or set ENABLE_GET_SUB_COMMENTS=false if sub-comments are not required in a browserless run","Ensure browser bootstrap completes before the comment-processing stage that calls this method"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import config\nif config.ENABLE_GET_SUB_COMMENTS and not client.playwright_page:\n    raise RuntimeError(\"ENABLE_GET_SUB_COMMENTS requires a browser page; disable it or attach playwright_page\")","typeGuard":"def can_fetch_sub_comments(client) -> bool:\n    import config\n    return (not config.ENABLE_GET_SUB_COMMENTS) or (\n        client.playwright_page is not None and not client.playwright_page.is_closed()\n    )","tryCatchPattern":null,"preventionTips":["Treat ENABLE_GET_SUB_COMMENTS=true as requiring a browser in the runbook","Validate config/browser pairing at crawler startup"],"tags":["playwright","tieba","sub-comments","configuration","validation"],"backgroundTag":null,"analyzedSha":"d6f7c5bb906b6dac40ddf343ef9e26438a3de092","analyzedAt":"2026-08-15T01:39:07.505Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}