NanmiCoder/MediaCrawler · error

playwright_page is required for browser-based note detail fe

Error message

playwright_page is required for browser-based note detail fetching

What it means

Raised by BaiduTieBaClient.get_note_by_id (media_platform/tieba/client.py:439) when self.playwright_page is None. Post-detail fetching is implemented by navigating a real browser page at the post URL and extracting embedded JSON, so a missing page makes the operation impossible. The guard fails fast with a clear message instead of an opaque NoneType error.

Source

Thrown at media_platform/tieba/client.py:439

            utils.logger.info(f"[BaiduTieBaClient.get_notes_by_keyword] Extracted {len(notes)} posts")
            return notes

        except Exception as e:
            utils.logger.error(f"[BaiduTieBaClient.get_notes_by_keyword] Search failed: {e}")
            raise

    async def get_note_by_id(self, note_id: str) -> TiebaNote:
        """
        Get post details by post ID (uses Playwright to access page, avoiding API detection)
        Args:
            note_id: Post ID

        Returns:
            TiebaNote: Post detail object
        """
        if not self.playwright_page:
            utils.logger.error("[BaiduTieBaClient.get_note_by_id] playwright_page is None, cannot use browser mode")
            raise Exception("playwright_page is required for browser-based note detail fetching")

        utils.logger.info(f"[BaiduTieBaClient.get_note_by_id] Accessing post detail API, note_id: {note_id}")

        try:
            api_data = await self._get_pc_page_data(note_id=note_id, page=1)
            note_detail = self._page_extractor.extract_note_detail_from_api(api_data)
            return note_detail

        except Exception as e:
            utils.logger.error(f"[BaiduTieBaClient.get_note_by_id] Failed to get post details: {e}")
            raise

    async def get_note_all_comments(
        self,
        note_detail: TiebaNote,
        crawl_interval: float = 1.0,
        callback: Optional[Callable] = None,
        max_count: int = 10,

View on GitHub (pinned to d6f7c5bb90)

Solutions

  1. Create and attach a Playwright page (via the standard crawler login flow) before calling get_note_by_id
  2. Verify the browser is still alive (page.is_closed()) and re-create the context if it crashed
  3. In tests, pass a mocked playwright_page exposing goto/content/evaluate
Defensive patterns

Strategy: type-guard

Validate before calling

assert client.playwright_page is not None and not client.playwright_page.is_closed(), "attach a live Playwright page first"

Type guard

def ready_for_detail_fetch(client) -> bool:
    return (
        getattr(client, "playwright_page", None) is not None
        and not client.playwright_page.is_closed()
    )

Prevention

When it happens

Trigger: Calling get_note_by_id(note_id) on a client constructed without playwright_page, or after the browser/page has been torn down. Any detail crawl (search-result follow-up, direct note_id lookup) under these conditions triggers it.

Common situations: Scripts that instantiate the client for testing/mocking without a browser; running detail crawl before the login/browser setup step completes; browser crash mid-session leaving a stale client.

Related errors


AI-assisted analysis of NanmiCoder/MediaCrawler@d6f7c5bb90 (2026-08-15). Data as JSON: /api/errors/e387222817c5c865. Report an issue: GitHub.