{"record":{"id":"8662b5a1f8ca728b","repo":"NanmiCoder/MediaCrawler","slug":"account-blocked","errorCode":null,"errorMessage":"account blocked","messagePattern":"account blocked","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"media_platform/tieba/client.py","lineNumber":271,"sourceCode":"        actual_proxy = proxy if proxy else self.default_ip_proxy\n\n        # Execute synchronous requests in thread pool\n        response = await asyncio.to_thread(\n            self._sync_request,\n            method,\n            url,\n            actual_proxy,\n            **kwargs\n        )\n\n        if response.status_code != 200:\n            utils.logger.error(f\"Request failed, method: {method}, url: {url}, status code: {response.status_code}\")\n            utils.logger.error(f\"Request failed, response: {response.text}\")\n            raise Exception(f\"Request failed, method: {method}, url: {url}, status code: {response.status_code}\")\n\n        if response.text == \"\" or response.text == \"blocked\":\n            utils.logger.error(f\"request params incorrect, response.text: {response.text}\")\n            raise Exception(\"account blocked\")\n\n        if return_ori_content:\n            return response.text\n\n        return response.json()\n\n    async def get(self, uri: str, params=None, return_ori_content=False, **kwargs) -> Any:\n        \"\"\"\n        GET request with header signing\n        Args:\n            uri: Request route\n            params: Request parameters\n            return_ori_content: Whether to return original content\n\n        Returns:\n\n        \"\"\"\n        final_uri = uri","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/NanmiCoder/MediaCrawler/blob/d6f7c5bb906b6dac40ddf343ef9e26438a3de092/media_platform/tieba/client.py#L253-L289","documentation":"Raised by BaiduTieBaClient.request (media_platform/tieba/client.py:271) when the response has status 200 but the body is empty or the literal string 'blocked'. Tieba returns this sentinel body instead of an HTTP error when it silently drops requests from suspected bots, so the client treats it as a hard failure. Despite the message wording, it almost always means the account/IP is flagged, not that request params are wrong.","triggerScenarios":"Any GET/POST through the Tieba client where response.text == '' or response.text == 'blocked': typically after many rapid sequential requests, when cookies identify a flagged account, or when the egress IP is on Baidu's blocklist.","commonSituations":"Long crawl runs that eventually get soft-blocked; running the crawler from a datacenter/VPS IP range Baidu distrusts; reusing cookies from an account that completed a captcha/verification elsewhere.","solutions":["Slow down: raise CRAWLER_MAX_SLEEP_SEC and per-call crawl_interval so requests look human","Switch egress IP (configure ip_pool proxy) since 'blocked' bodies usually indicate IP-level flagging","Re-login to obtain fresh cookies (delete stored browser state, use qrcode login)","If persistent, pause the crawl for hours — Baidu soft blocks often expire"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    data = await client.get(uri, params=params)\nexcept Exception as e:\n    if \"account blocked\" in str(e):\n        # switch egress IP or pause crawling; do not hammer the endpoint\n        await rotate_proxy_or_wait(hours=1)\n        raise","preventionTips":["Treat empty/200-'blocked' bodies as IP-level blocks: rotate proxies immediately","Add jittered delays between Tieba requests","Monitor for the first 'blocked' response and back off before retries compound the flag"],"tags":["anti-crawl","tieba","blocked","network"],"backgroundTag":null,"analyzedSha":"d6f7c5bb906b6dac40ddf343ef9e26438a3de092","analyzedAt":"2026-08-15T01:39:07.505Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}